{
    "version": "https://jsonfeed.org/version/1",
    "title": "Didier Lopes Blog",
    "home_page_url": "https://didierlopes.com/blog",
    "description": "Didier Lopes Blog",
    "items": [
        {
            "id": "https://didierlopes.com/blog/the-era-of-on-demand-software",
            "content_html": "<p>When agents can work in a loop while you do something else, time is removed from the equation. Welcome to the era of on-demand software.</p>\n<p>A couple of weeks back I went to a Pokemon TCG shop to buy some vintage WOTC cards. I'm just getting this collection started, so I had dozens of gaps to fill.</p>\n<p align=\"center\"><img width=\"400\" src=\"https://didierlopes.com/blog/2026-03-06-the-era-of-on-demand-software_1.webp\" alt=\"Pokemon card collection starting to shape up\"></p>\n<p align=\"center\" style=\"font-size:0.85em;margin-top:-0.5em\">My collection starting to shape up.</p>\n<br>\n<p>The guys at the counter weren't thrilled. Dozens of different vintage cards meant dozens of manual price lookups.</p>\n<p>So they triaged, anything marked shadowless went in one pile. Known valuable cards (e.g. Dragonite, Gengar,..) in another. Everything else? $1 flat, $3 for Shadowless. The rest they looked up individually on TCGPlayer.</p>\n<p>I said \"It would be nice to have software that does all this and totals it up, right?\"</p>\n<p>\"Yeah\" they said.</p>\n<p>First thing I did once I got home was write this Issue on my pokvault repo.</p>\n<p align=\"center\"><img width=\"800\" src=\"https://didierlopes.com/blog/2026-03-06-the-era-of-on-demand-software_2.webp\" alt=\"GitHub issue for card scanner feature\"></p>\n<br>\n<p>This is a fairly involved feature given that there's a lot to be done:</p>\n<ul>\n<li>Indexing all the card images universe</li>\n<li>Locate the card in the frame using a corner detection algorithm</li>\n<li>Encode the card with a vision model to compare with our indexed ones</li>\n<li>Show the best match cards</li>\n<li>Allow to add cards to the list (and their correct variant)</li>\n<li>Allow to edit price manually but also search manually</li>\n<li>Run on device and be fast</li>\n</ul>\n<br>\n<p>So I wasn't going to touch it until later...</p>\n<p><strong>Also me (given that I can hand off things to AI agents):</strong></p>\n<p align=\"center\"><img width=\"500\" src=\"https://didierlopes.com/blog/2026-03-06-the-era-of-on-demand-software_3.webp\" alt=\"Meme about doing it anyway\"></p>\n<br>\n<p>So I decomposed it in a few sub-tasks.</p>\n<ol>\n<li>Indexing all cards</li>\n<li>Get TCGPlayer reference images to near-100% similarity matches</li>\n<li>Handle my actual photos (odd angles, lighting, wear) with robust corner detection</li>\n<li>Implement the UI/UX I had in mind</li>\n</ol>\n<br>\n<p>Then I let Claude Code iterate in a loop while I did other things.</p>\n<p>Steps 2-3 took the longest. Claude tried different algorithms, compared performance, and <strong>this is the part that surprised me</strong>: it started tuning hyperparameters like an ML engineer would to improve retrieval accuracy.</p>\n<p><strong>Insane</strong>.</p>\n<p>After a few hours of back-and-forth, it worked. Exactly as I'd envisioned.</p>\n<p>My wife watched the whole thing. We'd just seen two guys at a shop struggle through a painfully manual process and here we were...</p>\n<p>Now I had a working solution without writing a single line of code myself.</p>\n<p>Bear in mind that I highlighted the problem perfectly, and had in my head exactly the UI/UX I wanted the user to have. And I also understood what choices the agent was doing on the ML pipeline. But still, I didn't touch any code manually myself - and the fact that it works exactly as I wanted is just incredible.</p>\n<p>You can test it here: <a href=\"https://pokvault.com/scanner\" target=\"_blank\" rel=\"noopener noreferrer\">https://pokvault.com/scanner</a></p>\n<p>I'm calling this the <strong>era of on-demand software</strong>.</p>\n<p>I've always been a builder. The only constraint was: <strong>time</strong>. But when agents can work in a loop while you do something else, time is removed from the equation.</p>\n<p>Plus, if you're a builder, it's never been a better moment for you. You shouldn't be in love with the act of coding, but with the act of creation itself. Because now everyone can create easily.</p>\n<p>But if you're not a builder, that's fine. Non-builders don't need the vision either, they just need the pain point.</p>\n<p>While in the past you would write that pain point on Google to look for existing solutions, now you can share your pain point with the agent and let it create a solution that solves your problem and that you can iterate with the agent to match your preferences.</p>\n<p>This is good.</p>\n<p>It will push for software companies to produce higher quality software built to stand the test of time.</p>\n<p>And if you're wondering - this is exactly why we're building OpenBB the way we are.</p>\n<p>The value isn't in the UI itself. It's in the overall infrastructure, the ease of data and agent integrations, the institutional-grade features that take years to build and maintain, and the relentless innovation. That's the moat.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/the-era-of-on-demand-software",
            "title": "The era of on-demand software",
            "summary": "When agents can work in a loop while you do something else, time is removed from the equation. Welcome to the era of on-demand software.",
            "date_modified": "2026-03-06T00:00:00.000Z",
            "tags": [
                "ai",
                "software-development",
                "agents",
                "openbb"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/no-room-to-hide",
            "content_html": "<p>AI is shrinking teams. Now every role has to earn its place.</p>\n<p>Not because companies are failing, but because AI lets fewer people do more.</p>\n<p>A startup that once needed 30 people to ship a product can now do it with 10. And this isn't just in startup-land. The best large companies are reorganizing around small, autonomous squads - 3 to 6 people - who take full ownership of a specific surface area. Think of a large org not as one team of 500, but as 80+ small teams, each operating with startup-like intensity and scope.</p>\n<p>Bezos was onto something with the two-pizza rule: <em>if a team can't be fed by two large pizzas, it's too big</em>. That instinct is proving more right than ever, not as a management preference, but as a structural inevitability.</p>\n<p>When teams shrink, roles blur. And that changes what it means to be valuable.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"what-small-teams-actually-look-like-now\">What small teams actually look like now<a href=\"https://didierlopes.com/blog/no-room-to-hide#what-small-teams-actually-look-like-now\" class=\"hash-link\" aria-label=\"Direct link to What small teams actually look like now\" title=\"Direct link to What small teams actually look like now\">​</a></h2>\n<p>I see this every day at OpenBB.</p>\n<p>Our previous community manager is currently the main maintainer behind our open source GitHub project with 62k+ GitHub stars. Our marketer uses GitHub Copilot to change copy directly on our website. Our designer codes her own wireframes. Our engineers build POCs in code rather than involving a product person. I use Claude Code to write features and get them to a reviewable state before handing them to our engineering team.</p>\n<p>None of those additional tasks were in the JD of each of these individuals. They were hired for their core expertise and their mindset, then AI expanded what they could credibly do.</p>\n<p>This is what a high-functioning small team looks like in 2026. Not people pretending to be experts in everything, but people with the right mentality taking ownership across boundaries that used to require separate hires.</p>\n<p>In the past, small startups had a few people who were jack of all trades and then a few specialists in their domain. Getting those specialists was the hard part, and often the main reason startups raised more capital. Now, AI bridges enough of that specialist capability that a team of curious, driven generalists can validate an idea and ship a product without needing to hire for every gap.</p>\n<p>And in larger companies, the shift is just as real. Historically, big orgs had massive teams where accountability was spread thin across dozens of people. There was always someone else in the chain of responsibility, which meant less incentive to get shit done. Some companies caught onto this early, Amazon's small team model being the obvious example, but now AI is accelerating the trend dramatically. The impact, in my opinion, will be much worse due to the previous overhire that has happened.</p>\n<p>I mean, Calendly has 500 employees which is an order of magnitude over Cal.com. DocSend (prev acquisition) was 50 people, Papermark is again an order of magnitude lower. Notion vs Obsidian. Airtable vs NocoDB. Qualtrics vs Formbricks. Asana vs Linear. There are <em>literally</em> countless examples like this. Yes, these aren't identical products, but the directional point holds.</p>\n<p>Sure, that previous headcount was used to \"support growth\" and not the other way around. But my point stands, you won't need anywhere near as much headcount to support growth.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"ai-supercharges-the-generalist\">AI supercharges the generalist<a href=\"https://didierlopes.com/blog/no-room-to-hide#ai-supercharges-the-generalist\" class=\"hash-link\" aria-label=\"Direct link to AI supercharges the generalist\" title=\"Direct link to AI supercharges the generalist\">​</a></h2>\n<p>AI has fundamentally changed the cost of learning and executing.</p>\n<p>A PM with no SQL experience can analyze database queries with any AI agent. A designer unfamiliar with frontend code can generate working React prototypes. A founder without legal training can draft and refine contracts on their own (not me though, I always use our GC).</p>\n<p>What used to require a course, a consultant, or a specialist now takes curiosity and a good prompt (and even the \"good\" is becoming debatable, as agents become more agentic).</p>\n<p>Jensen Huang put it well - <em>AI is the easiest application in the world to use</em>. <em>ChatGPT grew to nearly a billion users practically overnight. And if you're not sure how to use it? You ask it how to use it</em>.</p>\n<p>No tool in history has ever had that property.</p>\n<p>A single person on a small team can now credibly cover ground that would've required three hires two years ago. When every person on a 5-person squad can operate across 3-4 disciplines with AI assistance, you don't need 15 people. You need 5 versatile ones with the right tools.</p>\n<p>This is the structural reason small teams are winning. Not just culture. Not just speed. But the raw math of what's possible when every team member is AI-augmented.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"ai-collapses-the-middle\">AI collapses the middle<a href=\"https://didierlopes.com/blog/no-room-to-hide#ai-collapses-the-middle\" class=\"hash-link\" aria-label=\"Direct link to AI collapses the middle\" title=\"Direct link to AI collapses the middle\">​</a></h2>\n<p>If you're \"somewhat good\" at something, AI might already replace that edge.</p>\n<p>Three years of casual SQL experience? An AI copilot can match that. Decent at writing marketing copy? So is every LLM. Know your way around a spreadsheet? So does anyone with a prompt.</p>\n<p>The middle, where you're competent but not exceptional, is exactly where AI competes hardest.</p>\n<p>This is the flip side of the previous point. The same AI that supercharges the generalist is what collapses the edge for people who are merely decent at specific tasks.</p>\n<p>That means that the composition of teams is going to change, fast.</p>\n<p>What's emerging is a bifurcation:</p>\n<ul>\n<li><strong>Generalists</strong> - empowered by AI, fast-moving, versatile, multi-disciplinary.</li>\n<li><strong>Specialists</strong> - narrowly focused, deeply committed to a subject.</li>\n</ul>\n<br>\n<p>And soft skills are, potentially, becoming more important than ever.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"so-what-jobs-are-safe\">So what jobs are safe?<a href=\"https://didierlopes.com/blog/no-room-to-hide#so-what-jobs-are-safe\" class=\"hash-link\" aria-label=\"Direct link to So what jobs are safe?\" title=\"Direct link to So what jobs are safe?\">​</a></h2>\n<p>I like Jensen Huang's framework <em>if your job is the task, AI will replace you. If your job is more than the task, it won't. A lawyer's job isn't reading documents, it's helping people. Reading documents is part of the job, not the job.</em></p>\n<p>An analogy is if you're just chopping vegetables, you're replaceable. If you understand how to run a kitchen, from working with suppliers, serving customers, etc. - you're not.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"the-bar-has-risen-for-specialists\">The bar has risen for specialists<a href=\"https://didierlopes.com/blog/no-room-to-hide#the-bar-has-risen-for-specialists\" class=\"hash-link\" aria-label=\"Direct link to The bar has risen for specialists\" title=\"Direct link to The bar has risen for specialists\">​</a></h2>\n<p>Being a specialist today means something deeper than it used to. It means pursuing a level of depth and nuance that the base AI models struggle to replicate.</p>\n<p>Think of it like pursuing a PhD - not in the academic sense, but in the intensity of commitment.</p>\n<p>A specialist in compiler optimization might spend years mastering edge-case memory management. An enterprise sales leader might have decades of intuition about how procurement cycles actually work inside Fortune 500 organizations - the politics, the timing, the unwritten rules that no model has been trained on. Someone in regulatory affairs might know a specific market's compliance landscape so intimately that they can spot a risk before it surfaces in any dataset.</p>\n<p>In this case, the person who deeply understands a customer segment, who can navigate a specific regulatory landscape, who knows how to actually close a $500K enterprise deal - that's specialist depth too. And it's the kind of depth that becomes more valuable, not less, as AI handles everything around it.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"false-confidence\">False confidence<a href=\"https://didierlopes.com/blog/no-room-to-hide#false-confidence\" class=\"hash-link\" aria-label=\"Direct link to False confidence\" title=\"Direct link to False confidence\">​</a></h2>\n<p>The danger of AI-augmented generalists is misplaced confidence. Which is also known as \"Mount Stupid\" - which describes <em>the peak of false confidence where people with low competence or limited knowledge on a topic wrongly believe they are experts</em>. It represents a state of overconfidence, which often precedes realizing how much there is to learn.</p>\n<p>When a PM uses AI to write a SQL query, they get a result that looks right. It runs. It returns data. But they might not realize the query has a subtle join issue that inflates numbers by 15%. They don't know what they don't know, and the AI didn't flag it because it doesn't understand the business context.</p>\n<p>This is exactly why certain domain specialists on small teams are a must.</p>\n<p>I experience this firsthand weekly. I can be extremely productive with Claude Code. I can write features, refactor code, build things that work. But it usually cannot be merged as is. It always needs to be reviewed by our incredible infra engineers who have been working on our codebase for 4+ years, who know the ins and outs of the product, and who can see how a new feature will ripple through the system in ways I can't.</p>\n<p>This is a feature of the model. The generalist gets things to 80%. The specialist takes it to 100% - and if you're curious and have the right mindset, you can work with the specialist to increase your own knowledge in that domain. Same as before, but now with AI as the speed multiplier.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"the-ideal-small-team\">The ideal small team<a href=\"https://didierlopes.com/blog/no-room-to-hide#the-ideal-small-team\" class=\"hash-link\" aria-label=\"Direct link to The ideal small team\" title=\"Direct link to The ideal small team\">​</a></h2>\n<p>The ideal small team, whether inside a startup or a Fortune 500, increasingly looks like this: one or two deep specialists who own the core technical or domain complexity, surrounded by generalists who use AI to stretch across product, design, ops, marketing, and whatever else needs doing.</p>\n<p>This is how a 5-person team ships like a 20-person team used to. Mostly by the floor that gets raised due to AI. The generalists execute at a level that's good enough for most tasks, while the specialists handle what actually requires hard-won judgment, and catch the mistakes that AI-augmented confidence can miss.</p>\n<p>I saw a post the other day for a JD for a <em>vibe code cleanup specialist</em>, lmao. That's where we're heading, new roles that didn't exist six months ago.</p>\n<p>When people talk about startups outrunning incumbents, they often attribute it to culture or speed. But increasingly, the structural advantage is simpler: small teams with AI can cover the same surface area as large teams without it, at a fraction of the cost and with faster feedback loops. And large companies that adopt this model internally, breaking into dozens of small, autonomous squads, get the best of both worlds: startup speed with enterprise resources. But they are climbing uphill due to all previous friction that exists, so that's the window that startups have to execute.</p>\n<p>I increasingly think that we are heading towards a world where there are much fewer companies, but the ones that exist will be doing much much more.</p>\n<p>And that's somewhat scary.</p>\n<p>But what's scarier is not being valuable enough to be on one of these.</p>\n<p>Stay safe, stay curious.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/no-room-to-hide",
            "title": "No Room to Hide",
            "summary": "AI is shrinking teams. Now every role has to earn its place.",
            "date_modified": "2026-03-03T00:00:00.000Z",
            "tags": [
                "ai",
                "startups",
                "teams",
                "career"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/no-financial-terminal-will-survive",
            "content_html": "<p>No financial terminal <strong>in their current state</strong> will survive. (sorry for the clickbaity title eheh)</p>\n<p>Anyway, I would bet a lot on this - and want to explain my reasoning.</p>\n<p>But first let's understand what exists to-date to analyze financial data.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"the-bespoke-dashboard\">The bespoke dashboard<a href=\"https://didierlopes.com/blog/no-financial-terminal-will-survive#the-bespoke-dashboard\" class=\"hash-link\" aria-label=\"Direct link to The bespoke dashboard\" title=\"Direct link to The bespoke dashboard\">​</a></h2>\n<p>On one end, we have the custom-built dashboards, often started as weekend projects.</p>\n<p>A Streamlit app or React app or built on Lovable (the way it was produced doesn't matter), an internal tool some dev built over a weekend because the data vendor software didn't do what they needed. And it's great. It does that one thing really well. It was built by someone who understood the problem, for the people who had the problem.</p>\n<p>I'm a big fan of this. After all I do this for me all the time (e.g. my <a href=\"https://pokvault.com/\" target=\"_blank\" rel=\"noopener noreferrer\">pokemon website</a> that I use to track my binder).</p>\n<p>Unfortunately, the important part of the sentence is the \"<strong>ME</strong>\". Most financial software is not built with one single person in mind (unless you are <a href=\"https://josedonato.com/\" target=\"_blank\" rel=\"noopener noreferrer\">Jose Donato</a>, who has built his own <a href=\"https://cryexc.josedonato.com/\" target=\"_blank\" rel=\"noopener noreferrer\">Orderflow Terminal</a> for his own needs).</p>\n<p>So that means that the weekend custom application will face your team members. And one of them will ultimately need something slightly different. A different view. A new column. A different dataset plugged in. Now you're back to the person who built it. They make the change, but it shifts the experience for everyone else using it. So they build a second version. Then a third. Then the original builder leaves the firm and no one wants to touch the code.</p>\n<p>The dashboard was perfect the day it shipped.</p>\n<p>And it started dying the day after.</p>\n<p>There's a graveyard with millions of Streamlit apps that were built with the intent of increasing shareholder value, lmao.</p>\n<p>And I'm a massive Streamlit fan - I used to use it to prototype applications all the time. Note the use of \"prototype\", I never thought of it for something that it was not.</p>\n<p>My point is that these type of custom dashboards (Streamlit or not) are built for a moment in time, for a specific person's workflow, and the moment the context changes - which it will - you're stuck.</p>\n<p>Either you:</p>\n<ul>\n<li>Live with it - then you will complain the software sucks, which brings us back to the start of this essay</li>\n<li>Bother a developer to modify it - they may say no because it will impact others (so <strong>you</strong> will complain software sucks); or they may say yes which will impact others (so <strong>others</strong> will complain software sucks - at least eventually).</li>\n</ul>\n<br>\n<p>It's literally a losing battle.</p>\n<p>Unless you build your own open workspace. But more on this in a bit.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"bi-software-gets-the-model-right-but-not-for-finance\">BI software gets the model right, but not for finance<a href=\"https://didierlopes.com/blog/no-financial-terminal-will-survive#bi-software-gets-the-model-right-but-not-for-finance\" class=\"hash-link\" aria-label=\"Direct link to BI software gets the model right, but not for finance\" title=\"Direct link to BI software gets the model right, but not for finance\">​</a></h2>\n<p>I'm very bullish on BI software.</p>\n<p>Tableau (Salesforce), Power BI (Microsoft), Looker (Google) - they understood something important: the best software is the software you can shape to your own needs. They give you primitives. Building blocks. Drag this here, filter that there, connect to this data source. The user has agency.</p>\n<p>And for a lot of industries, this works extremely well.</p>\n<p>But for financial services, these dashboards are used for anything but market data analysis and insights.</p>\n<p>My hypothesis is that the building blocks are too generic. BI tools are horizontal by design - they're built to serve every industry, which means they're optimized for none. They don't incorporate financial symbology. They don't optimize for speed of data streaming. There's no concept of data staleness indicators, no natural way to put unstructured research next to structured time series, no role-based access at the widget level, no watchlist widget that triggers a workflow some place else.</p>\n<p>They have the right idea - composable, personal, user-controlled - but the wrong execution for finance.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"the-high-end-terminal-problem\">The high-end terminal problem<a href=\"https://didierlopes.com/blog/no-financial-terminal-will-survive#the-high-end-terminal-problem\" class=\"hash-link\" aria-label=\"Direct link to The high-end terminal problem\" title=\"Direct link to The high-end terminal problem\">​</a></h2>\n<p>On the other end, you have the high-end financial applications.</p>\n<p>These were designed with a single assumption: the analyst, quant, or PM will navigate the interface to find the information they need.</p>\n<p>And to be fair, these interfaces have been iterated over years/decades. They've been refined toward a local maxima: the configuration that optimizes for the most clients' happiness, utilizing the data they own, whilst not making it so complex that new users bounce.</p>\n<p>Credit where credit is due - this is an incredibly hard balance to get right.</p>\n<p>It's so hard, in fact, that companies like SPGI have significantly more data available through their APIs than they expose through their interface.</p>\n<p>Think about what that means. Please.</p>\n<p>The data exists.</p>\n<p>The capability exists.</p>\n<p>But the interface can't absorb it, because every new feature risks breaking the carefully calibrated experience for existing users.</p>\n<p>If you're trying to nail a specific workflow, you can't keep bolting on functionality to the UI. But you can keep creating API endpoints. So the interface becomes a frozen subset of what's actually possible.</p>\n<p>And here's where the data incentive makes it worse.</p>\n<p>These vendors own the data. Their interface is optimized to showcase <em>their</em> data in <em>their</em> way. There's no structural incentive to make it easy to bring in outside data or customize beyond what serves their distribution model. The UI isn't just static - it's static in a direction that serves the vendor, not you.</p>\n<p>So either the terminal does your workflow perfectly - because a PM somewhere decided your workflow was common enough to optimize for - or tough luck. You're forced into someone else's opinion of how you should do your job.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"the-same-failure-mode\">The same failure mode<a href=\"https://didierlopes.com/blog/no-financial-terminal-will-survive#the-same-failure-mode\" class=\"hash-link\" aria-label=\"Direct link to The same failure mode\" title=\"Direct link to The same failure mode\">​</a></h2>\n<p>These two worlds - the bespoke Streamlit dashboard and the enterprise terminal - look completely different on the surface. But they fail in the exact same way.</p>\n<p>Both end up static. Both take control away from the end user.</p>\n<p>The BI tool is dynamic for the <em>developer</em> - the person building the dashboard. They have full creative control. But the moment they ship it, it becomes static for the <em>consumer</em>. The end user gets a fixed view, and now we're right back in the terminal problem, except the UI is probably worse.</p>\n<p>The terminal is static for everyone. It was iterated into a local maxima that serves the average client reasonably well and no individual client perfectly. It can't be dynamic because that would break the very thing that makes it reliable.</p>\n<p>Neither model gives the end user real agency over their experience.</p>\n<p>And I think this is the core issue that the industry has been unable to solve.</p>\n<p>The spectrum from \"fully custom\" to \"fully productized\" has this big problem: <strong>no matter where you land on it, the end user eventually loses control.</strong></p>\n<p>You are literally forced to think of your workflows in the way <strong>someone else</strong> has decided they should be done.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"whats-needed\">What's needed<a href=\"https://didierlopes.com/blog/no-financial-terminal-will-survive#whats-needed\" class=\"hash-link\" aria-label=\"Direct link to What's needed\" title=\"Direct link to What's needed\">​</a></h2>\n<p>You need the primitives and abstractions of BI software - the composability, the building blocks, the user agency - delivered in a high-end, finance-native interface that understands the domain. Symbology. Real-time data. Staleness indicators. Structured and unstructured side by side. Role-based access at the widget level. The things that make financial workflows actually work.</p>\n<p>Rings a bell?</p>\n<p>Check <a href=\"https://openbb.co/solutions\" target=\"_blank\" rel=\"noopener noreferrer\">https://openbb.co/solutions</a>, where you can build custom financial applications with OpenBB's scalable infrastructure. From portfolio risk analysis to economic indicators, create enterprise-ready apps that transform fragmented data and AI tools into cohesive workflows.</p>\n<p>And - <strong>this is the important part</strong> - both the developer <em>and</em> the end user need to be able to control their experience. Not just the person who builds the dashboard. <strong>The analyst/PM who consumes it too.</strong></p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"where-ai-agents-fit\">Where AI agents fit<a href=\"https://didierlopes.com/blog/no-financial-terminal-will-survive#where-ai-agents-fit\" class=\"hash-link\" aria-label=\"Direct link to Where AI agents fit\" title=\"Direct link to Where AI agents fit\">​</a></h2>\n<p>\"But what about AI agents? Where do they fit?\"</p>\n<p>Well, they fit in both!!</p>\n<p>They can work as developers (when they are building applications) but also as the analyst/PM (when they are analyzing data in a dashboard as copilot).</p>\n<p>Here's my matrix on how I think about this:</p>\n<p><strong>Human as Developer.</strong> This is what exists today in BI tools or bespoke apps. A person builds a dashboard, configures widgets, connects data sources, designs the layout. They have full control - but it takes time, it requires skill, and the result is static for everyone else.</p>\n<p>In OpenBB, this exists and it's very important. Analysts and quant developers can build and customize their workspace exactly how they want. The main thing is that they are bringing data widgets to this workspace, connecting with the right tables on Snowflake, bringing in proprietary data. Full control. But unlike traditional BI, the building blocks are optimized for financial workflows.</p>\n<p>We literally have open sourced a <a href=\"https://github.com/OpenBB-finance/backends-for-openbb\" target=\"_blank\" rel=\"noopener noreferrer\">reference backend</a> to connect data to the workspace, but also <a href=\"https://github.com/OpenBB-finance/awesome-openbb\" target=\"_blank\" rel=\"noopener noreferrer\">examples of apps</a> built by the community.</p>\n<p><strong>Human as End User.</strong> This is the traditional terminal experience. You navigate, you click, you consume. The interface was built for you by someone else - a vendor PM, an internal developer - and you work within its constraints.</p>\n<p>But in OpenBB you have full control of that interface in the way the data is organized from the \"lego blocks\" that the development team has done.</p>\n<p><strong>AI Agent as Developer.</strong> This is what everyone is going crazy for. Coding agents. This is also why we are going to see an even bigger graveyard of bespoke apps, but many that might actually mature for narrow use cases. I think BI tools should be doing MUCH more here because they have the right primitives and could constrain the software built nicely.</p>\n<p>In our case, we think of how we can improve the process of building applications on our workspace via an agent. Not changing the UI itself because it's important to keep familiarity + brand consistency and for latency reasons, but the data being displayed and the analytics.</p>\n<p>I've built an <a href=\"https://skills.sh/openbb-finance/backends-for-openbb/openbb-app-builder\" target=\"_blank\" rel=\"noopener noreferrer\">OpenBB app builder</a> SKILL for agents to help them close that building ability gap.</p>\n<p><strong>AI Agent as End User.</strong> This is where it starts to get interesting. An AI agent that consumes the workspace like a human would - reading data from widgets, interpreting charts, understanding the current state of a dashboard - and then acts on it. It can look at your portfolio view, add a widget to the dashboard with data that is of interest based on that portfolio. It can read a research note displayed in one widget and cross-reference it against the financial data in another.</p>\n<p>The agent isn't just answering questions in a chat box. It's <em>seeing</em> the same workspace you see, understanding the context of what's in front of you but also other widgets, and adding value on top of it. The workspace becomes shared context between you and the agent.</p>\n<p>This <a href=\"https://docs.openbb.co/workspace/analysts/ai-features/generative-ui\" target=\"_blank\" rel=\"noopener noreferrer\">generative UI</a> capability is something that we are only getting better. I believe in this so much that this is where I spend most of my time building at OpenBB. We are adding capabilities to fully control the workspace and its widgets organization to create perfect layout for analysis on the fly.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"the-boundary-dissolves\">The boundary dissolves<a href=\"https://didierlopes.com/blog/no-financial-terminal-will-survive#the-boundary-dissolves\" class=\"hash-link\" aria-label=\"Direct link to The boundary dissolves\" title=\"Direct link to The boundary dissolves\">​</a></h2>\n<p>When you put these four quadrants together, something important happens: <strong>the boundary between building software and using software dissolves</strong>.</p>\n<p>Funnily enough when discussing OpenBB positioning, this has been one of the topics we have discussed the most.</p>\n<p>That is because I have believed, for a while, that analysts will start owning more developer tasks. Data point <a href=\"https://openbb.co/blog/from-excel-to-agents-rebuilding-the-macro-research-workflow-for-the-ai-era\" target=\"_blank\" rel=\"noopener noreferrer\">here</a> and <a href=\"https://github.com/MattMaximo/CryptoBB\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>, both built by analysts pre-Opus 4.5.</p>\n<p>And to accelerate giving control to analysts/PMs, there's a need for an open workspace.</p>\n<p><strong>A workspace that is personal, malleable, and responsive to context.</strong></p>\n<p>A human can build a dashboard in the morning. An AI agent can modify it based on new data at noon. The human can rearrange it for a client meeting at 2pm. The agent can strip it down to the essentials for a quick mobile check at 6pm.</p>\n<p>The workspace is alive.</p>\n<p>Not because it's generating novel UI from scratch - that would be disorienting. But because it's assembling and reassembling familiar pieces based on who's using it, what they're doing, and what the data demands.</p>\n<p>This is what \"software should be personal\" actually means. Not \"you get to pick your theme color\".</p>\n<p>Personal as in: the software reflects your workflow, your data, your context, your role - and it adapts as those things change. Whether the one changing it is you or an AI agent working on your behalf.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"why-the-old-model-doesnt-survive\">Why the old model doesn't survive<a href=\"https://didierlopes.com/blog/no-financial-terminal-will-survive#why-the-old-model-doesnt-survive\" class=\"hash-link\" aria-label=\"Direct link to Why the old model doesn't survive\" title=\"Direct link to Why the old model doesn't survive\">​</a></h2>\n<p>The old model - where a PM defines the interface, ships it, and you live with it - doesn't survive this shift.</p>\n<p>Not because the interfaces were bad. Many of them were excellent, refined over years by smart people who understood their users deeply. But they were built for a world where the interface <em>had</em> to be static, because the only way to make it dynamic was to hire a developer. And developers are expensive, slow, and their changes affect everyone.</p>\n<p>AI agents remove that constraint. When the cost of modifying an interface drops to near zero - when you can reshape your workspace with a sentence - there's no reason to accept a static view ever again.</p>\n<p>The high-end terminals will still have great data. The BI tools will still have great primitives. But I believe the future is in a platform that combines finance-native building blocks with true composability for both humans and AI agents.</p>\n<p>Software should be personal.</p>\n<p>Now it finally can be.</p>\n<p><a href=\"https://pro.openbb.co/\" target=\"_blank\" rel=\"noopener noreferrer\">https://pro.openbb.co/</a></p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/no-financial-terminal-will-survive",
            "title": "No financial terminal will survive.",
            "summary": "No financial terminal in their current state will survive. Here's why the future belongs to open, composable workspaces.",
            "date_modified": "2026-02-24T00:00:00.000Z",
            "tags": [
                "finance",
                "openbb",
                "ai",
                "product"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/what-if-you-could-create-any-report",
            "content_html": "<p>Bringing Claude Code Skills into the OpenBB Workspace to create custom reports right where your data lives.</p>\n<p>Last week I shared a video building a Claude Code Skill from scratch. It took a DBS Report and converted it into a Skill so I could produce DBS-style reports with any financial data. (more info <a href=\"https://didierlopes.com/blog/how-you-can-build-and-share-a-claude-code-skill/\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>)</p>\n<p><a href=\"https://www.linkedin.com/in/magnus-samuelsen/\" target=\"_blank\" rel=\"noopener noreferrer\">Magnus</a> has been working on one of my favorite projects: building <a href=\"https://openbb.co/blog/building-ai-agents-for-openbb-workspace-with-pydantic-ai\" target=\"_blank\" rel=\"noopener noreferrer\">AI agents for the OpenBB Workspace with Pydantic AI</a>. He saw my video and had the idea to bring skills like this directly into the Workspace.</p>\n<p>Not just to replicate what I had done, but because he saw the potential.</p>\n<p>The ability to create custom reports in the place where you already have all your data!</p>\n<p>So he built it.</p>\n<p>Using its very own <a href=\"https://github.com/MagnusS0/openbb-pydantic-ai\" target=\"_blank\" rel=\"noopener noreferrer\">OpenBB Pydantic AI framework</a>, he made it possible to discover and run skills inside the Workspace via code.</p>\n<p>You can literally check the PR <a href=\"https://github.com/MagnusS0/openbb-pydantic-ai/pull/7\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<p align=\"center\"><img width=\"800\" src=\"https://didierlopes.com/blog/2026-02-20-what-if-you-could-create-any-report.webp\" alt=\"OpenBB Workspace with Skills integration\"></p>\n<br>\n<p align=\"center\"><img width=\"800\" src=\"https://didierlopes.com/blog/2026-02-20-what-if-you-could-create-any-report_1.webp\" alt=\"OpenBB Workspace Skills demo\"></p>\n<br>\n<p>We're bringing skills to the Workspace very soon. But the fact that the community is already finding ways to do it programmatically - that's just amazing.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/what-if-you-could-create-any-report",
            "title": "What if you could create any report - right where your data lives?",
            "summary": "Bringing Claude Code Skills into the OpenBB Workspace to create custom reports right where your data lives.",
            "date_modified": "2026-02-20T00:00:00.000Z",
            "tags": [
                "openbb",
                "ai",
                "open-source",
                "skills"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/the-context-wars-in-financial-services",
            "content_html": "<p>As AI collapses the enterprise application stack, the context layer becomes the most valuable part of the technology stack in financial services.</p>\n<p><strong>A quick note:</strong> I've moved this newsletter from Beehiiv to Substack. Nothing changes on your end - just letting you know. Now, onto this week's piece.</p>\n<p>Matt Slotnick recently wrote an excellent essay on \"<a href=\"https://x.com/matt_slotnick/status/2016968805034192962\" target=\"_blank\" rel=\"noopener noreferrer\">Context Rules Everything Around Me: The Future Of Enterprise Applications</a>\" about how AI collapses the enterprise application stack. As agents take over more work, existing applications get relegated to data sources. The value shifts up to a data layer, a context layer on top of it, and an interaction layer where agents and people actually do work.</p>\n<p>He's writing about enterprise software broadly - Salesforce, Workday, ServiceNow. But I think the implications for financial software are even more dramatic. In finance, proprietary insight is the product. Which means the context layer is everything.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2026-02-13-the-context-wars-in-financial-services.webp\" alt=\"Context Rules Everything Around Me diagram\"></p>\n<br>\n<p>Context is what happens when you connect everything a firm knows. When your agent doesn't just see your portfolio positions - it sees the positions, the research that led to them, the macro environment they sit in, the risk limits they're constrained by, the client preferences they serve, and the market data that's moving right now.</p>\n<p>That's the difference between an AI that gives you generic answers and one that reasons about your portfolio the way a senior analyst would.</p>\n<p>Particularly in a world of Opus 4.6 and Codex 5.3.</p>\n<p>And that's why the context layer is where the leverage is. The applications underneath are commoditizing - their value shifts from the interface they provide to the data and workflow state they hold. The interaction layer on top matters, but it's downstream - the quality of the context determines the quality of everything above it. A beautifully designed workspace powered by thin context is just a pretty terminal with generic answers.</p>\n<p>For financial firms, this layer determines what your agents know, what they can reason about, and how useful they actually are when it matters.</p>\n<p>Every company in the space sees this shift coming. And the instinct from most of them is: \"<em>We'll build the context layer for you. Give us your data, and we'll manage the intelligence on top.</em>\"</p>\n<p>I think that's the wrong framing.</p>\n<p>When a vendor says \"we'll manage your context\" what they're really saying is: \"<em>trust us with the most valuable layer of your entire technology stack\"</em>. The layer that determines what your agents see, what they act on, and how they reason about your business.</p>\n<p>For any firm where differentiation matters - where the way you analyze, decide, and act is your edge - that should be a non-starter.</p>\n<p>And there's a subtler problem. If a vendor owns your context layer, every firm on that vendor gets a version of context shaped by the same system, the same defaults, the same biases. Your \"proprietary\" intelligence starts looking a lot like everyone else's.</p>\n<p>The right framing: companies should focus on being the underlying tech that enables firms to <strong>own their own context</strong>. Not build it for them. Not host it for them. Give them the tools to build it themselves, on their own infrastructure, under their own control.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"the-platform-cannot-also-be-the-data-vendor\">The platform cannot also be the data vendor<a href=\"https://didierlopes.com/blog/the-context-wars-in-financial-services#the-platform-cannot-also-be-the-data-vendor\" class=\"hash-link\" aria-label=\"Direct link to The platform cannot also be the data vendor\" title=\"Direct link to The platform cannot also be the data vendor\">​</a></h2>\n<p>This leads to a structural point that I keep repeating.</p>\n<p>If the context layer needs to be owned by the firm, then the platform enabling it <strong>cannot also be the data vendor</strong>.</p>\n<p>The moment you own the data, you have an incentive to privilege your own feeds and content. That breaks the neutrality that makes the orchestration layer trustworthy. It's the same reason you don't want your operating system to also be the only application developer. <strong>The OS works because it's agnostic to what runs on it.</strong></p>\n<p>A financial workspace needs that same structural neutrality. Internal data, vendor data, proprietary models, open-source tools - they all need to be first-class citizens. The platform's job is to orchestrate, not compete.</p>\n<p>The company that wins this layer wins by being the best orchestrator. Not the best data vendor, not the best AI model - the best at bringing everything together in a way that's fast, familiar, and built around how each firm actually works.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"on-premise-is-the-consequence\">On-premise is the consequence<a href=\"https://didierlopes.com/blog/the-context-wars-in-financial-services#on-premise-is-the-consequence\" class=\"hash-link\" aria-label=\"Direct link to On-premise is the consequence\" title=\"Direct link to On-premise is the consequence\">​</a></h2>\n<p>This is the part that ties it all together - and it's where we're putting our money where our mouth is.</p>\n<p>If you believe firms should own their context, then you have to go all the way. That means the platform runs on the firm's infrastructure, where the data never leaves their walls.</p>\n<p>This is the architectural consequence of everything above. If the context layer is the most valuable part of the stack, and it's built from the firm's proprietary data, research, and workflows, then it can't live on someone else's servers. Full stop.</p>\n<p>For firms that want the same principle with less infrastructure overhead, we built OpenBB as a <a href=\"https://openbb.co/blog/openbb-launches-openbb-workspace-as-a-snowflake-native-app-on-snowflake-marketplace\" target=\"_blank\" rel=\"noopener noreferrer\">Snowflake Native App</a>. It runs on your Snowflake instance - your data stays in your environment, you control the compute, and you're up and running without a six-month deployment. Same ownership, easier on-ramp.</p>\n<p>Either way, the firm owns the context. We provide the workspace - the finance-native building blocks, the open ecosystem for data providers and widget builders, the agentic layer that both humans and AI can operate on. But the intelligence, the data, the workflows? That stays with you.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"context-compounds\">Context compounds<a href=\"https://didierlopes.com/blog/the-context-wars-in-financial-services#context-compounds\" class=\"hash-link\" aria-label=\"Direct link to Context compounds\" title=\"Direct link to Context compounds\">​</a></h2>\n<p>Another beautiful thing with context is that it isn't static. Every workflow executed, every analysis run, every agent interaction generates more context. What your analysts researched, how they structured their analysis, what patterns the agents flagged, what decisions were made and why - all of that feeds back into the system.</p>\n<p>If that compounding happens on your infrastructure, your firm gets smarter over time. Your agents get better because they're learning from your firm's accumulated intelligence. That's a real defensible edge.</p>\n<p>If that compounding happens on a vendor's infrastructure, the vendor captures that value. They get smarter. Their product gets better. And your proprietary workflows become training data for a system that serves everyone else.</p>\n<p>The open ecosystem isn't a feature. It's the architecture. And paradoxically, it's the moat - because the platform that lets everyone build on it will always have more integrations and capabilities than the one that tries to do it all alone.</p>\n<p>Openness compounds.</p>\n<p>In a world where context rules everything, the platform with the most context wins. But the context has to belong to the firm, not the platform.</p>\n<p>The firms that understand this will build on infrastructure that gives them that ownership.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/the-context-wars-in-financial-services",
            "title": "The context wars in financial services",
            "summary": "As AI collapses the enterprise application stack, the context layer becomes the most valuable part of the technology stack in financial services.",
            "date_modified": "2026-02-13T00:00:00.000Z",
            "tags": [
                "ai",
                "finance",
                "openbb",
                "enterprise"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/learn-how-to-let-an-agent-build-your-dream-app-whilst-you-sleep",
            "content_html": "<p>Opus 4.5 run with my vision of a better Pokemon vault website and I just sit there and watched it do it end-to-end.</p>\n<p>I hope you like the title of this one, very proud of it. (No LLMs were used in the making of the title).</p>\n<p>Everyone was talking about Ralph a few weeks ago (this one has been in the vault for a bit!). I'm not much of a Simpson guy so I didn't fully get the reference - but anyway. I wanted to get my hands dirty to understand what all the fuss is about.</p>\n<p>Here are 3 resources that will get you up-to-speed on the topic:</p>\n<ul>\n<li><a href=\"https://www.youtube.com/watch?v=_IK18goX4X8\" target=\"_blank\" rel=\"noopener noreferrer\">Simple walkthrough of what Ralph Wiggum loop is</a></li>\n<li><a href=\"https://www.youtube.com/watch?v=4Nna09dG_c0\" target=\"_blank\" rel=\"noopener noreferrer\">Video from the creator of the method on how to use it</a></li>\n<li><a href=\"https://x.com/ryancarson/status/2008548371712135632\" target=\"_blank\" rel=\"noopener noreferrer\">Text breakdown by Ryan</a></li>\n</ul>\n<br>\n<p><strong>TL;DR:</strong></p>\n<p>Provided you have plan with a list of tasks in <em>IMPLEMENTATION-PLAN.md</em>, here's the loop:</p>\n<ol>\n<li>Agent picks up a TODO task</li>\n<li>Agent executes it</li>\n<li>Agent updates <em>PROGRESS.md</em> to add that such a task is DONE</li>\n<li>Agent logs decisions it made in a <em>LOGS.md</em></li>\n<li>Agent updates <em>IMPLEMENTATION-PLAN.md</em> in case it needs to add another sub-task</li>\n</ol>\n<br>\n<p>And then it stops, and kicks the loop again.</p>\n<p>The benefit is that it starts from a clear context window from scratch, so there's nothing polluting it essentially.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"building-an-app-with-a-couple-hours-of-work\">Building an app with a couple hours of \"work\"<a href=\"https://didierlopes.com/blog/learn-how-to-let-an-agent-build-your-dream-app-whilst-you-sleep#building-an-app-with-a-couple-hours-of-work\" class=\"hash-link\" aria-label=\"Direct link to Building an app with a couple hours of &quot;work&quot;\" title=\"Direct link to Building an app with a couple hours of &quot;work&quot;\">​</a></h2>\n<p>But as you know, talk is cheap. I like to learn in the trenches. So I put this to test.</p>\n<p>I was checking Pokemon card websites and they were either:</p>\n<ul>\n<li>Filled with ads</li>\n<li>Slow</li>\n<li>Confusing</li>\n<li>Lacking features</li>\n</ul>\n<br>\n<p>Most of the time, multiple of these.</p>\n<p>Sooooo, I detailed a plan of my vision for a simple Pokemon website and let the agent code it overnight.</p>\n<p><strong>AND HOLYSHIT.</strong></p>\n<p align=\"center\"><img width=\"800\" src=\"https://didierlopes.com/blog/2026-02-09-learn-how-to-let-an-agent-build-your-dream-app_1.webp\" alt=\"Pokemon vault app - card collection view\"></p>\n<p align=\"center\"><img width=\"800\" src=\"https://didierlopes.com/blog/2026-02-09-learn-how-to-let-an-agent-build-your-dream-app_2.webp\" alt=\"Pokemon vault app - set overview\"></p>\n<br>\n<p>This is a side-project that previously I wouldn't have started because it would just consume too much time that I don't have. But now, not anymore when I can delegate SO MUCH.</p>\n<p>Here's what this application did:</p>\n<ul>\n<li>Browse and search Pokemon cards across sets</li>\n<li>Track which cards I own in my collection</li>\n<li>Mark the cards I'm chasing to complete sets</li>\n<li>Login credentials</li>\n<li>Share my collections</li>\n</ul>\n<br>\n<p>Exactly what I needed.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"the-setup\">The Setup<a href=\"https://didierlopes.com/blog/learn-how-to-let-an-agent-build-your-dream-app-whilst-you-sleep#the-setup\" class=\"hash-link\" aria-label=\"Direct link to The Setup\" title=\"Direct link to The Setup\">​</a></h2>\n<p>I'm not going to talk about my Ralph setup, I think the jury is still out on that one in terms of best way to use that framework. Maybe it's literally just a bash file? Maybe there's a UI component to it for non-technical folks? I don't know.</p>\n<p>Personally, I think labs will just have their base coding agents do it BTS.</p>\n<p>Anyway, I'm gonna talk about a few concepts that are critical to achieve this level of automation:</p>\n<p><strong>1. Skip the permissions dance</strong></p>\n<p>I ran Claude Code with <code>--dangerously-skip-permissions</code>. Yes, the flag sounds scary. That's the point - it's opt-in friction. But when you know what you're building and you trust your environment, removing the constant \"approve this file change?\" interruptions lets the agent stay in flow.</p>\n<p><strong>2. Give it eyes</strong></p>\n<p>I enabled browser access with <code>/chrome</code>. This let Claude actually see what it was building, navigate the UI, spot visual bugs, and iterate on the design. It's one thing to write code. It's another to see the output and adjust. The browser made Claude a full-stack builder. This tight feedback loop is critical.</p>\n<p><strong>3. Plan extensively upfront</strong></p>\n<p>Before writing a single line of code, I use plan mode SHIFT + TAB in CC. I described the entire vision: the features, the user flows, the data model, how authentication should work, where data should live. Claude built a comprehensive plan, and I refined it. We went back and forth on edge cases and UX decisions before any implementation started.</p>\n<p>This is the part that felt most like my actual job. Scoping. Clarifying. Making sure the spec is tight before engineering begins.</p>\n<p><strong>4. Speak instead of typing</strong></p>\n<p>If you prefer to speak because otherwise you would be typing a lot in this initial section you can use something like Wispr Flow to communicate with the terminal. This can be done by just pressing a button and off you go.</p>\n<p><strong>5. Let it run</strong></p>\n<p>Then I used the Ralph Wiggum loop. You tell Claude to keep going, keep iterating, keep improving - and you walk away. Like literally. Go sleep or do something else. You can ask for it to commit every time it does a new iteration and once you come back you can see all the work that it did on its own.</p>\n<p><strong>6. Spin multiple agents in parallel</strong></p>\n<p>If you are in the laptop you can actually spin up an agent in parallel to do the work in a different area of the code. Because they are pushing to the same branch, and models are trained with a ton of data from GitHub they will be familiar with git versioning and you won't have to worry about git conflicts. It's like having an engineer working on the frontend, another one on the backend, another on the auth, etc…</p>\n<p>You can even use other models to do this - on the image below I'm using Claude on the left and Gemini (via Antigravity) on the right. Both controlling the browser.</p>\n<p align=\"center\"><img width=\"800\" src=\"https://didierlopes.com/blog/2026-02-09-learn-how-to-let-an-agent-build-your-dream-app_3.webp\" alt=\"Multiple agents working in parallel - Claude and Gemini\"></p>\n<br>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"the-pm-as-wizard\">The PM as Wizard<a href=\"https://didierlopes.com/blog/learn-how-to-let-an-agent-build-your-dream-app-whilst-you-sleep#the-pm-as-wizard\" class=\"hash-link\" aria-label=\"Direct link to The PM as Wizard\" title=\"Direct link to The PM as Wizard\">​</a></h2>\n<p>Being a PM has always been about translating vision into actionable instructions for engineers. Clear requirements. Well-scoped tickets. Defined acceptance criteria.</p>\n<p>That skill set just became a superpower.</p>\n<p>Because now you're not waiting for sprint capacity. You're not negotiating priorities with three other teams. You're not blocked on that senior engineer who's on vacation. You write the spec, you give it to the agent, and it executes.</p>\n<p>The bottleneck was never the PM's ability to envision. It was the translation layer - getting other humans to build what's in your head, with all the communication overhead, context loss, and calendar conflicts that entails.</p>\n<p>That layer is collapsing.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"its-never-been-a-better-time-to-be-a-pm\">It's never been a better time to be a PM<a href=\"https://didierlopes.com/blog/learn-how-to-let-an-agent-build-your-dream-app-whilst-you-sleep#its-never-been-a-better-time-to-be-a-pm\" class=\"hash-link\" aria-label=\"Direct link to It's never been a better time to be a PM\" title=\"Direct link to It's never been a better time to be a PM\">​</a></h2>\n<p>Or maybe more accurately: it's never been a better time to be someone who knows how to communicate clearly.</p>\n<p>The technical bar for shipping software just dropped through the floor. But the vision bar? The clarity bar? That's higher than ever. Because if you can articulate exactly what you want - really specify it, with the edge cases and the user flows and the \"what happens when\" - you can build it.</p>\n<p>The people who will thrive are the clearest thinkers and communicators.</p>\n<p>I didn't have in my bingo card that developers might be deprecated sooner than PMs, but here we are.</p>\n<p><strong>ALSO</strong></p>\n<p>I'm not saying engineering is dead. Complex systems, novel architectures, performance optimization at scale - there's deep craft there that isn't going anywhere, for now.</p>\n<p>But a lot of software isn't that. A lot of software is \"I need a thing that does X, Y, and Z, and looks decent, and works.\"</p>\n<p>If you're a PM reading this: <strong>start building</strong>. Not because you need to learn to code, but because you already know to talk to people (agents) who know how to.</p>\n<p>Now you have an agent that can execute your specs in hours and that doesn't get tired, distracted, etc.</p>\n<p>The power shifted.</p>\n<p>Use it.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/learn-how-to-let-an-agent-build-your-dream-app-whilst-you-sleep",
            "title": "Learn how to let an agent build your dream app whilst you sleep",
            "summary": "Opus 4.5 run with my vision of a better Pokemon vault website and I just sit there and watched it do it end-to-end.",
            "date_modified": "2026-02-09T00:00:00.000Z",
            "tags": [
                "ai",
                "claude",
                "agents",
                "software-development",
                "product-management"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/how-you-can-build-and-share-a-claude-code-skill",
            "content_html": "<p>Creating a skill to generate a financial report with a specific branding</p>\n<p>In a <a href=\"https://didierlopes.com/blog/how-i-turned-days-of-developer-training-into-a-skill\">previous post</a>, I shared how I turned days of developer training into a skill that lets anyone build <a href=\"https://openbb.co/\" target=\"_blank\" rel=\"noopener noreferrer\">OpenBB</a> apps in minutes.</p>\n<p>Today I'm going to show you how to build a skill from scratch.</p>\n<p><strong>Here's the counterintuitive thing:</strong> as models get smarter, the premium on well-crafted skills goes <em>up</em>, not down.</p>\n<p>Most people assume better models mean less need for customization.</p>\n<p><strong>The opposite is true.</strong></p>\n<p>A 5% improvement in base capability compounds with a well-designed skill. The skill becomes the multiplier.</p>\n<p>So this is my attempt to show you how to create a skill from scratch and iterate on it until it's good enough to share with someone else.</p>\n<p>For this example, I'm going to build a <strong>financial report generation skill</strong>.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"the-process\">The Process<a href=\"https://didierlopes.com/blog/how-you-can-build-and-share-a-claude-code-skill#the-process\" class=\"hash-link\" aria-label=\"Direct link to The Process\" title=\"Direct link to The Process\">​</a></h2>\n<p>I also recorded a video walkthrough which you can find here:</p>\n<div class=\"flex place-items-center justify-center items-center rounded-sm mx-auto\"><iframe src=\"https://www.youtube.com/embed/HRalrMR8k_0\" width=\"800\" height=\"400\"></iframe></div>\n<br>\n<p>Here's the approach I use:</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"1-create-a-new-repo\">1. Create a new repo<a href=\"https://didierlopes.com/blog/how-you-can-build-and-share-a-claude-code-skill#1-create-a-new-repo\" class=\"hash-link\" aria-label=\"Direct link to 1. Create a new repo\" title=\"Direct link to 1. Create a new repo\">​</a></h3>\n<p>Start with a clean folder.</p>\n<p>This will become your skill directory.</p>\n<div class=\"language-bash codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-bash codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">mkdir dbs-report-skill</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">cd dbs-report-skill</span><br></span></code></pre></div></div>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"2-add-example-reports-you-like\">2. Add example reports you like<a href=\"https://didierlopes.com/blog/how-you-can-build-and-share-a-claude-code-skill#2-add-example-reports-you-like\" class=\"hash-link\" aria-label=\"Direct link to 2. Add example reports you like\" title=\"Direct link to 2. Add example reports you like\">​</a></h3>\n<p>Find 2-3 reports that represent the style and quality you're targeting. These become your \"ground truth\".</p>\n<p>Drop them into the repo. PDFs, screenshots, whatever format they're in.</p>\n<p>The key is having concrete examples, not abstract descriptions of what you want.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"3-have-claude-analyze-the-design-in-detail\">3. Have Claude analyze the design in detail<a href=\"https://didierlopes.com/blog/how-you-can-build-and-share-a-claude-code-skill#3-have-claude-analyze-the-design-in-detail\" class=\"hash-link\" aria-label=\"Direct link to 3. Have Claude analyze the design in detail\" title=\"Direct link to 3. Have Claude analyze the design in detail\">​</a></h3>\n<p>Tell Claude to study the reports and extract <em>everything</em> it would need to recreate them:</p>\n<ul>\n<li><strong>Visual design</strong>: Layout, typography, spacing, color palette, margins</li>\n<li><strong>Content structure</strong>: Section hierarchy, data relationships, narrative flow</li>\n<li><strong>Formatting patterns</strong>: How tables are styled, how charts are positioned, how callouts work</li>\n</ul>\n<br>\n<p>Ask Claude to be exhaustive.</p>\n<p>You want it to notice things you wouldn't think to mention.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"4-generate-a-report-with-mock-data\">4. Generate a report with mock data<a href=\"https://didierlopes.com/blog/how-you-can-build-and-share-a-claude-code-skill#4-generate-a-report-with-mock-data\" class=\"hash-link\" aria-label=\"Direct link to 4. Generate a report with mock data\" title=\"Direct link to 4. Generate a report with mock data\">​</a></h3>\n<p>Now test whether Claude actually absorbed the design language.</p>\n<p>Ask it to create a report in that exact style, but with completely made-up data.</p>\n<p>This isolates the skill from data dependencies. If the mock report looks wrong, it's a design problem, not a data problem.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"5-iterate-until-its-right\">5. Iterate until it's right<a href=\"https://didierlopes.com/blog/how-you-can-build-and-share-a-claude-code-skill#5-iterate-until-its-right\" class=\"hash-link\" aria-label=\"Direct link to 5. Iterate until it's right\" title=\"Direct link to 5. Iterate until it's right\">​</a></h3>\n<p>This is the loop:</p>\n<ol>\n<li>Review the output</li>\n<li>Identify what's off</li>\n<li>Update the skill instructions</li>\n<li>Regenerate</li>\n<li>Repeat</li>\n</ol>\n<br>\n<p>Don't move on until a single prompt produces a report that matches your examples.</p>\n<p>Don't keep running claude yourself either, let it iterate on its own until it thinks that the report it created is actually fairly similar style-wise from the ground-truth ones in the folder.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"6-connect-real-data\">6. Connect real data<a href=\"https://didierlopes.com/blog/how-you-can-build-and-share-a-claude-code-skill#6-connect-real-data\" class=\"hash-link\" aria-label=\"Direct link to 6. Connect real data\" title=\"Direct link to 6. Connect real data\">​</a></h3>\n<p>Now add the data layer.</p>\n<p>Give Claude access to real financial data via MCP servers and web search.</p>\n<p>In this example, I'm going to connect with Carbon Arc MCP and utilize web search.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"7-generate-a-real-report\">7. Generate a real report<a href=\"https://didierlopes.com/blog/how-you-can-build-and-share-a-claude-code-skill#7-generate-a-real-report\" class=\"hash-link\" aria-label=\"Direct link to 7. Generate a real report\" title=\"Direct link to 7. Generate a real report\">​</a></h3>\n<p>The moment of truth.</p>\n<p>Ask Claude to create a report on an actual company using the skill and real data sources.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"where-the-skill-lives\">Where the Skill lives<a href=\"https://didierlopes.com/blog/how-you-can-build-and-share-a-claude-code-skill#where-the-skill-lives\" class=\"hash-link\" aria-label=\"Direct link to Where the Skill lives\" title=\"Direct link to Where the Skill lives\">​</a></h2>\n<p>Once you're done, the skill exists in your <code>.claude</code> folder (or wherever you configured skills to live).</p>\n<p>The structure looks like this:</p>\n<div class=\"language-text codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-text codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">financial-report-skill/</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">├── SKILL.md           # The instructions</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">├── assets/            # Templates, fonts, images</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">└── references/        # Example reports, style guides</span><br></span></code></pre></div></div>\n<p>The SKILL.md file is the brain. It contains:</p>\n<ul>\n<li><strong>Frontmatter</strong>: Name and description (this is what triggers the skill)</li>\n<li><strong>Instructions</strong>: The procedural knowledge Claude needs</li>\n</ul>\n<br>\n<p>Here's a simplified example of what the frontmatter looks like:</p>\n<div class=\"language-markdown codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-markdown codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token front-matter-block punctuation\" style=\"color:rgb(248, 248, 242)\">---</span><span class=\"token front-matter-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token front-matter-block\"></span><span class=\"token front-matter-block front-matter yaml language-yaml key atrule\">name</span><span class=\"token front-matter-block front-matter yaml language-yaml punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token front-matter-block front-matter yaml language-yaml\"> dbs</span><span class=\"token front-matter-block front-matter yaml language-yaml punctuation\" style=\"color:rgb(248, 248, 242)\">-</span><span class=\"token front-matter-block front-matter yaml language-yaml\">report</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token front-matter-block front-matter yaml language-yaml\"></span><span class=\"token front-matter-block front-matter yaml language-yaml key atrule\">description</span><span class=\"token front-matter-block front-matter yaml language-yaml punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token front-matter-block front-matter yaml language-yaml\"> Generate a DBS Group Research US Equity Research report in HTML format. Use this skill when the user asks to create</span><span class=\"token front-matter-block front-matter yaml language-yaml punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token front-matter-block front-matter yaml language-yaml\"> generate</span><span class=\"token front-matter-block front-matter yaml language-yaml punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token front-matter-block front-matter yaml language-yaml\"> or produce a DBS</span><span class=\"token front-matter-block front-matter yaml language-yaml punctuation\" style=\"color:rgb(248, 248, 242)\">-</span><span class=\"token front-matter-block front-matter yaml language-yaml\">style equity research report for a company. The skill produces a pixel</span><span class=\"token front-matter-block front-matter yaml language-yaml punctuation\" style=\"color:rgb(248, 248, 242)\">-</span><span class=\"token front-matter-block front-matter yaml language-yaml\">perfect reproduction of the DBS report format including cover page</span><span class=\"token front-matter-block front-matter yaml language-yaml punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token front-matter-block front-matter yaml language-yaml\"> financial tables</span><span class=\"token front-matter-block front-matter yaml language-yaml punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token front-matter-block front-matter yaml language-yaml\"> ratings history</span><span class=\"token front-matter-block front-matter yaml language-yaml punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token front-matter-block front-matter yaml language-yaml\"> and disclaimer pages.</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token front-matter-block front-matter yaml language-yaml\"></span><span class=\"token front-matter-block front-matter yaml language-yaml key atrule\">argument-hint</span><span class=\"token front-matter-block front-matter yaml language-yaml punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token front-matter-block front-matter yaml language-yaml\"> &lt;company</span><span class=\"token front-matter-block front-matter yaml language-yaml punctuation\" style=\"color:rgb(248, 248, 242)\">-</span><span class=\"token front-matter-block front-matter yaml language-yaml\">name</span><span class=\"token front-matter-block front-matter yaml language-yaml punctuation\" style=\"color:rgb(248, 248, 242)\">&gt;</span><span class=\"token front-matter-block front-matter yaml language-yaml\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token front-matter-block front-matter yaml language-yaml\"></span><span class=\"token front-matter-block front-matter yaml language-yaml key atrule\">user-invocable</span><span class=\"token front-matter-block front-matter yaml language-yaml punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token front-matter-block front-matter yaml language-yaml\"> </span><span class=\"token front-matter-block front-matter yaml language-yaml boolean important\">true</span><span class=\"token front-matter-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token front-matter-block\"></span><span class=\"token front-matter-block punctuation\" style=\"color:rgb(248, 248, 242)\">---</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\"></span><span class=\"token title important punctuation\" style=\"color:rgb(248, 248, 242)\">#</span><span class=\"token title important\"> DBS Group Research -- US Equity Research Report Generator</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">You are generating a </span><span class=\"token bold punctuation\" style=\"color:rgb(248, 248, 242)\">**</span><span class=\"token bold content\">DBS Group Research US Equity Research report</span><span class=\"token bold punctuation\" style=\"color:rgb(248, 248, 242)\">**</span><span class=\"token plain\"> in HTML format. The output must be a single self-contained HTML file that, when opened in a browser and printed to PDF, is visually indistinguishable ...</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">...</span><br></span></code></pre></div></div>\n<p>The description is critical. It's how Claude knows when to use the skill.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"sharing-the-skill\">Sharing the Skill<a href=\"https://didierlopes.com/blog/how-you-can-build-and-share-a-claude-code-skill#sharing-the-skill\" class=\"hash-link\" aria-label=\"Direct link to Sharing the Skill\" title=\"Direct link to Sharing the Skill\">​</a></h2>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"option-1-send-the-file-directly\">Option 1: Send the file directly<a href=\"https://didierlopes.com/blog/how-you-can-build-and-share-a-claude-code-skill#option-1-send-the-file-directly\" class=\"hash-link\" aria-label=\"Direct link to Option 1: Send the file directly\" title=\"Direct link to Option 1: Send the file directly\">​</a></h3>\n<p>Just share the skill folder.</p>\n<p>The recipient drops it into their skills directory. <strong>I love this about skills.</strong></p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"option-2-publish-to-skillssh\">Option 2: Publish to skills.sh<a href=\"https://didierlopes.com/blog/how-you-can-build-and-share-a-claude-code-skill#option-2-publish-to-skillssh\" class=\"hash-link\" aria-label=\"Direct link to Option 2: Publish to skills.sh\" title=\"Direct link to Option 2: Publish to skills.sh\">​</a></h3>\n<p>If you open source your skill repository, it becomes available through <a href=\"https://skills.sh/\" target=\"_blank\" rel=\"noopener noreferrer\">skills.sh</a>.</p>\n<p>Anyone can install it with:</p>\n<div class=\"language-bash codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-bash codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">npx skills add &lt;your-github-org&gt;/&lt;your-repo&gt;</span><br></span></code></pre></div></div>\n<p>And that means you can add it with:</p>\n<div class=\"language-bash codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-bash codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">npx skills add didierlopes/dbs-report-skill</span><br></span></code></pre></div></div>\n<p>Then they ask Claude to generate a financial report, and the skill triggers automatically.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"why-you-should-care\">Why you should care<a href=\"https://didierlopes.com/blog/how-you-can-build-and-share-a-claude-code-skill#why-you-should-care\" class=\"hash-link\" aria-label=\"Direct link to Why you should care\" title=\"Direct link to Why you should care\">​</a></h2>\n<p>We're entering an era where the raw intelligence of models keeps climbing.</p>\n<p>But intelligence without context is generic. The skill is what makes it <em>yours</em>.</p>\n<p>It encodes your taste, your standards, your workflow.</p>\n<p>The model provides the horsepower; the skill provides the steering.</p>\n<p>And the better the model gets, the more it can do with a well-crafted skill.</p>\n<p>Start building yours.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/how-you-can-build-and-share-a-claude-code-skill",
            "title": "How you can build and share a Claude Code skill",
            "summary": "Creating a skill to generate a financial report with a specific branding",
            "date_modified": "2026-02-03T00:00:00.000Z",
            "tags": [
                "ai",
                "claude",
                "skills",
                "developer-experience"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/how-i-turned-days-of-developer-training-into-a-skill",
            "content_html": "<p>I materialized my knowledge of how to build OpenBB apps, and days of building alongside users and clients, into a SKILL that you can give your agents. So you can start building apps in minutes.</p>\n<p>Recently, we added support for YouTube widgets.</p>\n<p>So I sent a video to our marketing person explaining that I could add a YouTube video to each tab of our <a href=\"https://github.com/OpenBB-finance/backends-for-openbb/tree/main\" target=\"_blank\" rel=\"noopener noreferrer\">reference backend application</a> to onboard developers on how to build apps/widgets on OpenBB.</p>\n<p align=\"center\"><img width=\"800\" src=\"https://didierlopes.com/blog/2026-01-27-how-i-turned-days-of-developer-training-into-a-skill_1.webp\" alt=\"Slack message about YouTube videos\"></p>\n<br>\n<p>She liked the idea, and I was set to do it.</p>\n<p>But then I kept postponing actually doing it.</p>\n<p>Not because I didn't have the time, but because I thought my time was better spent doing something different.</p>\n<p><strong>Stick with me.</strong></p>\n<p>We run developer training workshops where we work hands-on with teams to build OpenBB apps - <a href=\"https://openbb.link/workshops\" target=\"_blank\" rel=\"noopener noreferrer\">https://openbb.link/workshops</a></p>\n<p>But not everyone needs that level of depth to get started and even those who do, could benefit from a head start.</p>\n<p>Still, whether it's videos or docs, developers need to dedicate time to learning the craft. And some people are very successful at it, I constantly see people building incredible apps on the workspace by just reading the docs. Examples here: <a href=\"https://openbb.co/solutions\" target=\"_blank\" rel=\"noopener noreferrer\">https://openbb.co/solutions</a></p>\n<p>But their workflow could be faster if we were there. Next to them providing suggestions on how to apply grouping between widgets, utilize a widget settings more efficiently, mark data as stale, etc…</p>\n<p>However, in 2026, we can actually create digital twins.</p>\n<p>What if developers could tap into the same mental framework I use when building apps, available anytime, without scheduling a call?</p>\n<p><em>You know where I am heading right?</em></p>\n<p>So I provided my full framework on how I build apps on OpenBB and had Claude help me turn that into a skill.</p>\n<p>But this isn't enough because I have a lot of bias as I know what I'm looking for.</p>\n<p>So I tested and iterated - in a loop.</p>\n<p>I pretended I was a user who knew nothing about OpenBB and asked it to build something. Three use cases:</p>\n<ul>\n<li>From scratch and generic - build a crypto app</li>\n<li>From an existing GitHub repo code - could be just the data</li>\n<li>From looking at an existing website</li>\n</ul>\n<br>\n<p>After each attempt, I'd ask the model to analyze its work - did it learn something new? Could anything be added to the skill?</p>\n<p>If a one-shot prompt didn't result in a working app, I'd immediately fix the skill.</p>\n<p>Iterate until it works.</p>\n<p>Ship.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"and-it-worked\">And it worked.<a href=\"https://didierlopes.com/blog/how-i-turned-days-of-developer-training-into-a-skill#and-it-worked\" class=\"hash-link\" aria-label=\"Direct link to And it worked.\" title=\"Direct link to And it worked.\">​</a></h2>\n<p>After my prompt, here's what Claude outputs:</p>\n<p align=\"center\"><img width=\"800\" src=\"https://didierlopes.com/blog/2026-01-27-how-i-turned-days-of-developer-training-into-a-skill_2.webp\" alt=\"Claude output - part 1\"></p>\n<p align=\"center\"><img width=\"800\" src=\"https://didierlopes.com/blog/2026-01-27-how-i-turned-days-of-developer-training-into-a-skill_3.webp\" alt=\"Claude output - part 2\"></p>\n<br>\n<p>And then I said: \"Ship it\".</p>\n<p>Only to come back to this working app:</p>\n<p align=\"center\"><img width=\"800\" src=\"https://didierlopes.com/blog/2026-01-27-how-i-turned-days-of-developer-training-into-a-skill_4.webp\" alt=\"Working app - tab 1\"></p>\n<p align=\"center\"><img width=\"800\" src=\"https://didierlopes.com/blog/2026-01-27-how-i-turned-days-of-developer-training-into-a-skill_5.webp\" alt=\"Working app - tab 2\"></p>\n<p align=\"center\"><img width=\"800\" src=\"https://didierlopes.com/blog/2026-01-27-how-i-turned-days-of-developer-training-into-a-skill_6.webp\" alt=\"Working app - tab 3\"></p>\n<br>\n<p>You can now do this by running</p>\n<div class=\"language-bash codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-bash codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">npx skills add openbb-finance/backends-for-openbb</span><br></span></code></pre></div></div>\n<p>and asking Claude to build an OpenBB app from within that environment.</p>\n<p>Excited to see what you build.</p>\n<p>Just reach out.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/how-i-turned-days-of-developer-training-into-a-skill",
            "title": "How I turned days of developer training into a skill you can use in minutes",
            "summary": "I materialized my knowledge of how to build OpenBB apps, and days of building alongside users and clients, into a SKILL that you can give your agents. So you can start building apps in minutes.",
            "date_modified": "2026-01-27T00:00:00.000Z",
            "tags": [
                "ai",
                "claude",
                "skills",
                "openbb",
                "developer-experience"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/the-year-of-consolidation",
            "content_html": "<p>Technical debt is about to hit levels we've never seen.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"the-building-boom\">The building boom<a href=\"https://didierlopes.com/blog/the-year-of-consolidation#the-building-boom\" class=\"hash-link\" aria-label=\"Direct link to The building boom\" title=\"Direct link to The building boom\">​</a></h2>\n<p>The bar is so low to build apps.</p>\n<p>Like literally so low.</p>\n<p>You are literally able to ship a working application without knowing a single thing about software engineering. This has never happened in the history of human kind! Like literally.</p>\n<p>So now anything you want to do you can get it done in a couple of hours using one of the latest coding agents.</p>\n<p>The friction of building collapsed overnight.</p>\n<p>I'm not just talking about engineers. Data scientists are doing it (Boris, creator of Claude Code, actually has a funny anecdote about it <a href=\"https://youtu.be/AmdLVWMdjOk?si=ARe83kshNQgoAMUa&amp;t=4588\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>); Analysts are doing it; PMs are doing it; damn even C-level execs are doing it.</p>\n<p>This is great right?</p>\n<p><strong>Kind of.</strong></p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"the-frankenstein-problem\">The Frankenstein problem<a href=\"https://didierlopes.com/blog/the-year-of-consolidation#the-frankenstein-problem\" class=\"hash-link\" aria-label=\"Direct link to The Frankenstein problem\" title=\"Direct link to The Frankenstein problem\">​</a></h2>\n<p>When everyone can build apps in a few hours, you don't get a streamlined organization.</p>\n<p>You get Frankenstein.</p>\n<p>Think about what actually happens inside a 500-person firm when building becomes nearly free:</p>\n<ul>\n<li>The equity research team builds a custom earnings dashboard</li>\n<li>The credit team builds their own version - same data sources, different assumptions</li>\n<li>The macro team builds another - same widget types, different logic</li>\n<li>Portfolio management builds yet another - because the other three don't quite fit their workflow</li>\n</ul>\n<br>\n<p>Four dashboards. Four codebases. Four sets of assumptions. Four potential points of failure. Zero shared foundation.</p>\n<p>Now multiply this across every function, every team, every use case that someone thought was \"quick enough to just build myself\".</p>\n<p>What do you get?</p>\n<p>A graveyard of internal tools that nobody maintains, nobody documents, and nobody knows how to find.</p>\n<p>I literally have seen this happening already - usually in the form of 10+ Streamlit apps.</p>\n<p>The other issue is that once you want to add an intelligence layer to these apps, it requires very expensive AI developers to build them. But you are reinventing the wheel every single time to build an agent familiar with that specific app that was built.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"the-visibility-crisis\">The visibility crisis<a href=\"https://didierlopes.com/blog/the-year-of-consolidation#the-visibility-crisis\" class=\"hash-link\" aria-label=\"Direct link to The visibility crisis\" title=\"Direct link to The visibility crisis\">​</a></h2>\n<p>Here's a question you should start asking your CTO/CIO:</p>\n<p>\"Do you know how many internal AI tools your organization built last year?\"</p>\n<p>Most can't answer.</p>\n<p>Not because they don't care - because they genuinely don't know.</p>\n<p>When a quant builds a custom model in a Jupyter notebook, does that count? When an analyst creates a Streamlit app for their team, is that tracked? When someone spins up a quick automation using Claude, does IT even know it exists?</p>\n<p>The honest answer at most firms: <em>no visibility whatsoever</em>.</p>\n<p>This creates two problems:</p>\n<p><strong>1. Duplication at scale</strong></p>\n<p>I've seen the same widget rebuilt several times (and over) across different teams at the same firm. Not because people are lazy - because they didn't know it already existed. There's no central registry.</p>\n<p>No shared workspace.</p>\n<p><strong>2. Governance nightmares</strong></p>\n<p>When you don't know what's being used, you can't govern it. You can't audit it. You can't secure it. Every one of those \"quick internal tools\" is a potential compliance risk, a data leak waiting to happen, a black box that someone critical to the business depends on.</p>\n<p>At a 10-person startup, this can be managed. At a 2,000-person financial institution, it can't.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"the-technical-debt-tsunami\">The technical debt tsunami<a href=\"https://didierlopes.com/blog/the-year-of-consolidation#the-technical-debt-tsunami\" class=\"hash-link\" aria-label=\"Direct link to The technical debt tsunami\" title=\"Direct link to The technical debt tsunami\">​</a></h2>\n<p>Here's the thing about the \"build fast\" era: the debt comes due.</p>\n<p>Every prototype that skipped proper authentication? <strong>Debt</strong>.</p>\n<p>Every dashboard that hardcoded assumptions? <strong>Debt</strong>.</p>\n<p>Every tool built on a free tier API that's about to change pricing? <strong>Debt</strong>.</p>\n<p>Every widget that only one person understands? <strong>Debt</strong>.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2026-01-23-the-year-of-consolidation_1.webp\" alt=\"Technical debt tweet\"></p>\n<br>\n<p>We've talked about technical debt for decades. But what's coming is different in scale.</p>\n<p>Previously, technical debt accumulated slowly. Building was hard enough that the rate of debt creation was naturally constrained.</p>\n<p>Now? The rate of creation has 10x'd while the rate of maintenance has stayed flat.</p>\n<p>The math doesn't work.</p>\n<p>I predict 2026 will see the first wave of \"<strong>AI tool cleanup</strong>\" initiatives at major enterprises - massive projects to audit, consolidate, or kill the hundreds of internal tools that were built.</p>\n<p>Maybe the best ones stick? But even then, you will need a way to consolidate what they do for other departments.</p>\n<p>Some firms will do this proactively.</p>\n<p>Most will be forced into it after something breaks.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"the-consolidation-imperative\">The consolidation imperative<a href=\"https://didierlopes.com/blog/the-year-of-consolidation#the-consolidation-imperative\" class=\"hash-link\" aria-label=\"Direct link to The consolidation imperative\" title=\"Direct link to The consolidation imperative\">​</a></h2>\n<p>So what's the answer?</p>\n<p>It's not \"stop building\". There's too much at stake.</p>\n<p>The answer is consolidation. A uniform layer that sits in the middle.</p>\n<p>Think about what actually needs to happen:</p>\n<p><strong>One data layer.</strong> Every tool, every dashboard, every agent pulling from the same governed, normalized data sources. Not twelve different connections to the same API with twelve different authentication schemes.</p>\n<p><strong>One workspace.</strong> A central place where tools get built, discovered, and shared. Where leadership can actually see what exists. Where teams can find what's already been built before rebuilding it.</p>\n<p><strong>One governance framework.</strong> Audit logs. Permissions. Compliance controls. Applied consistently across every tool, not retrofitted onto whatever someone spun up in an afternoon.</p>\n<p>The idea is to make innovation sustainable.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"where-openbb-fits\">Where OpenBB Fits<a href=\"https://didierlopes.com/blog/the-year-of-consolidation#where-openbb-fits\" class=\"hash-link\" aria-label=\"Direct link to Where OpenBB Fits\" title=\"Direct link to Where OpenBB Fits\">​</a></h2>\n<p>This is exactly why we built OpenBB the way we did.</p>\n<p>Not as another point solution. Not as another tool to add to the pile.</p>\n<p>As the uniform layer.</p>\n<p>One workspace where every widget, every workflow, every agent operates from the same foundation. Data normalized once, available everywhere - workspace, API, Excel, agents. Governance built in from day one.</p>\n<p>When your equity team builds a dashboard, it's discoverable. When your credit team needs something similar, they extend it rather than rebuild it. When leadership asks \"what AI tools are we using\", there's an actual answer.</p>\n<p>The infrastructure layer that lets you keep building fast - without the Frankenstein.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"the-fork-in-the-road\">The fork in the road<a href=\"https://didierlopes.com/blog/the-year-of-consolidation#the-fork-in-the-road\" class=\"hash-link\" aria-label=\"Direct link to The fork in the road\" title=\"Direct link to The fork in the road\">​</a></h2>\n<p>2026 is going to separate two types of organizations:</p>\n<ul>\n<li><strong>The consolidators:</strong> Firms that recognize the mess, centralize proactively, and emerge with a clean, governed, scalable foundation for AI-native workflows.</li>\n<li><strong>The firefighters:</strong> Firms that keep building on shaky foundations until something break - then scramble to clean up while their competitors pull ahead.</li>\n</ul>\n<br>\n<p>The consolidation is coming either way.</p>\n<p align=\"center\"><img width=\"800\" src=\"https://didierlopes.com/blog/2026-01-23-the-year-of-consolidation_2.webp\" alt=\"OpenBB Workspace - Apps\"></p>\n<p align=\"center\" style=\"font-size:0.85em;margin-top:-0.5em\">OpenBB Workspace - Apps</p>\n<br>\n<p>And we are building towards it.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/the-year-of-consolidation",
            "title": "2026: The Year of Consolidation",
            "summary": "Technical debt is about to hit levels we've never seen.",
            "date_modified": "2026-01-23T00:00:00.000Z",
            "tags": [
                "ai",
                "enterprise",
                "technical-debt",
                "openbb"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/chat-is-not-the-future-interface-its-the-future-router",
            "content_html": "<p>Why AI won't replace your apps, but your home screen</p>\n<p>There's a narrative floating around AI circles that goes something like this: \"In the future, we won't need apps. We'll just chat with AI and it will do everything for us.\"</p>\n<p>It sounds compelling. <strong>But it's wrong.</strong></p>\n<p>Not completely wrong - there's a kernel of truth buried in there. But the maximalist version of this take? The one where chat interfaces subsume everything? <strong>That's a fantasy that ignores how humans actually want to interact with information.</strong></p>\n<p>Let me show you why.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"the-evolution-is-already-telling-us-the-answer\">The evolution is already telling us the answer<a href=\"https://didierlopes.com/blog/chat-is-not-the-future-interface-its-the-future-router#the-evolution-is-already-telling-us-the-answer\" class=\"hash-link\" aria-label=\"Direct link to The evolution is already telling us the answer\" title=\"Direct link to The evolution is already telling us the answer\">​</a></h2>\n<p>Watch the progression over the past two years:</p>\n<p>First, we had chat only. GPT-3, early ChatGPT. Text in, text out. Revolutionary at the time.</p>\n<p>Then we got charts generated in chat. Cool, but you're squinting at a chart generated between paragraphs of text. And you can only interact with it via panel drag, zooms, etc… very limiting.</p>\n<p>Then Claude introduced Artifacts - a side panel where code, documents, and visualizations could live <em>outside</em> the chat stream. Suddenly the chat wasn't the destination. It was the control panel.</p>\n<p>Then Perplexity started generating full workspace-like experiences.</p>\n<p>Then Claude showed up in Excel. Not replacing Excel. Living inside it.</p>\n<p>Notice the direction here? We're not converging on chat. <strong>We're expanding out of it.</strong></p>\n<p>Every major AI interface innovation of the past months has been about escaping the constraints of the chat window, <strong>not doubling down on them.</strong></p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"the-generate-ui-on-the-fly-fantasy\">The \"generate UI on the fly\" fantasy<a href=\"https://didierlopes.com/blog/chat-is-not-the-future-interface-its-the-future-router#the-generate-ui-on-the-fly-fantasy\" class=\"hash-link\" aria-label=\"Direct link to The &quot;generate UI on the fly&quot; fantasy\" title=\"Direct link to The &quot;generate UI on the fly&quot; fantasy\">​</a></h2>\n<p>There's a related idea that's equally seductive: AI will just generate custom interfaces on the fly, perfectly tailored to your task. No need for pre-built apps. The UI materializes from your intent.</p>\n<p>It's a beautiful vision. <strong>But it doesn't work due to latency.</strong></p>\n<p>By the time the AI understands your request, generates a custom interface, renders it, and lets you interact with it - you could have just opened the app. The cognitive overhead of waiting for a UI to materialize, then learning that UI, then realizing it's not quite right, then asking for modifications... it compounds.</p>\n<p>For this to work, the strong foundation needs to be set in advance. Which means you're not really using \"generated UI\". You're using pre-built components that get assembled based on your request.</p>\n<p>And at that point, the chat isn't the interface. <strong>It's just the router.</strong></p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"the-chat-only-life-a-thought-experiment\">The chat-only life: a thought experiment<a href=\"https://didierlopes.com/blog/chat-is-not-the-future-interface-its-the-future-router#the-chat-only-life-a-thought-experiment\" class=\"hash-link\" aria-label=\"Direct link to The chat-only life: a thought experiment\" title=\"Direct link to The chat-only life: a thought experiment\">​</a></h2>\n<p>Let's stress-test the chat maximalist position. Imagine running your entire digital life through a chat interface:</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"chat-only-instagram\">Chat-only Instagram<a href=\"https://didierlopes.com/blog/chat-is-not-the-future-interface-its-the-future-router#chat-only-instagram\" class=\"hash-link\" aria-label=\"Direct link to Chat-only Instagram\" title=\"Direct link to Chat-only Instagram\">​</a></h3>\n<p align=\"center\"><img width=\"800\" src=\"https://didierlopes.com/blog/2026-01-20-chat-is-not-the-future-interface_1.webp\" alt=\"Chat-only Instagram thought experiment\"></p>\n<br>\n<p>\"Show me my feed.\" You get a list of descriptions. \"Show me the third image.\" You see it. \"Like it.\" Done. \"Show me comments.\" You read them in a text block. \"Post a comment.\" You type it.</p>\n<p>Yup, this would suck.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"chat-only-calendar\">Chat-only calendar<a href=\"https://didierlopes.com/blog/chat-is-not-the-future-interface-its-the-future-router#chat-only-calendar\" class=\"hash-link\" aria-label=\"Direct link to Chat-only calendar\" title=\"Direct link to Chat-only calendar\">​</a></h3>\n<p align=\"center\"><img width=\"800\" src=\"https://didierlopes.com/blog/2026-01-20-chat-is-not-the-future-interface_2.webp\" alt=\"Chat-only calendar thought experiment\"></p>\n<br>\n<p>\"What's on my schedule tomorrow?\" Fine, that works. \"Move my 2pm to 3pm.\" Also fine. \"Show me my week and help me find 90 minutes for deep work.\" Now you want to <em>see</em> the gaps. You want to drag and drop. You want spatial reasoning.</p>\n<p>Chat is great for queries but is actually very bad for manipulation of complex, visual information.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"chat-only-map\">Chat-only Map<a href=\"https://didierlopes.com/blog/chat-is-not-the-future-interface-its-the-future-router#chat-only-map\" class=\"hash-link\" aria-label=\"Direct link to Chat-only Map\" title=\"Direct link to Chat-only Map\">​</a></h3>\n<p align=\"center\"><img width=\"800\" src=\"https://didierlopes.com/blog/2026-01-20-chat-is-not-the-future-interface_3.webp\" alt=\"Chat-only map thought experiment\"></p>\n<br>\n<p>\"What are the directions to the stadium?\" You get a turn-by-turn list: \"Head north, turn right on Main St...\". \"What's the ETA?\" You get a time. \"Show me the area and help me find a scenic route with less traffic.\" Now you want to see the green park, the red traffic lines. You want to drag your route to a different street. You want spatial reasoning…</p>\n<p>And if you get the map embedded on the chat response, then you want to interact with it. Which at that point you might as well be in the Maps app.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"chat-only-jira\">Chat-only Jira<a href=\"https://didierlopes.com/blog/chat-is-not-the-future-interface-its-the-future-router#chat-only-jira\" class=\"hash-link\" aria-label=\"Direct link to Chat-only Jira\" title=\"Direct link to Chat-only Jira\">​</a></h3>\n<p align=\"center\"><img width=\"800\" src=\"https://didierlopes.com/blog/2026-01-20-chat-is-not-the-future-interface_4.webp\" alt=\"Chat-only Jira thought experiment\"></p>\n<br>\n<p>\"Show me my sprint backlog.\" You get a text list. \"Move ticket PROJ-447 to In Progress.\" Done. \"Show me the board.\"</p>\n<p>This could actually work, except that you lose the drag and drop experience and the ability to zoom-in a ticket to get more details or change assignee etc.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"what-chat-actually-replaces\">What chat actually replaces<a href=\"https://didierlopes.com/blog/chat-is-not-the-future-interface-its-the-future-router#what-chat-actually-replaces\" class=\"hash-link\" aria-label=\"Direct link to What chat actually replaces\" title=\"Direct link to What chat actually replaces\">​</a></h2>\n<p>Here's the reframe: <strong>chat doesn't replace apps. Chat replaces the router to apps.</strong></p>\n<p>Think about your laptop right now. You have a dock with icons. You click an icon, an app opens. The dock is a routing mechanism - a way to get to the thing you actually want to use.</p>\n<p align=\"center\"><img width=\"800\" src=\"https://didierlopes.com/blog/2026-01-20-chat-is-not-the-future-interface_5.webp\" alt=\"Laptop dock with icons\"></p>\n<br>\n<p>Your phone works the same way. Grid of icons. Tap one. App opens.</p>\n<p>This routing mechanism is dumb. It requires you to know which app you need before you can get there. It forces you to think in terms of applications rather than tasks.</p>\n<p>Chat fixes this.</p>\n<p>\"I need to analyze last quarter's revenue by region\" → routes you to a data workspace with the right context loaded.</p>\n<p>\"Schedule a call with David next week\" → routes you to your calendar with suggested slots.</p>\n<p>\"Draft a response to that investor email\" → routes you to a writing environment with the email thread as context.</p>\n<p>The chat is the new dock. The new home screen. The new command line. But you still land somewhere richer than a text box.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"the-chatgpt-apps-announcement\">The ChatGPT Apps announcement<a href=\"https://didierlopes.com/blog/chat-is-not-the-future-interface-its-the-future-router#the-chatgpt-apps-announcement\" class=\"hash-link\" aria-label=\"Direct link to The ChatGPT Apps announcement\" title=\"Direct link to The ChatGPT Apps announcement\">​</a></h2>\n<p>They're acknowledging that chat alone isn't enough. That users need richer interfaces for certain tasks. That the \"just chat\" paradigm has limits.</p>\n<p>The interface layer still matters.</p>\n<p>It just gets summoned differently now.</p>\n<p>And this time it lives on the cloud first as opposed to <a href=\"https://openai.com/index/computer-using-agent/\" target=\"_blank\" rel=\"noopener noreferrer\">Computer Use Agents</a>, which relies on user's operating system.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"where-this-leaves-us\">Where this leaves us<a href=\"https://didierlopes.com/blog/chat-is-not-the-future-interface-its-the-future-router#where-this-leaves-us\" class=\"hash-link\" aria-label=\"Direct link to Where this leaves us\" title=\"Direct link to Where this leaves us\">​</a></h2>\n<p>Chat is genuinely transformative. For quick queries, brainstorming, first drafts, routing decisions - it's unbeatable.</p>\n<p>But it's a steering wheel, not the engine.</p>\n<p>Companies will build AI that drops you into the right experience at the right moment. The ones that don't will keep trying to stuff spreadsheets and calendars and design tools into a text box.</p>\n<p>The future isn't chat replacing interfaces. It's chat as the universal entry point to interfaces that actually respect how humans think.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"appendix\">Appendix<a href=\"https://didierlopes.com/blog/chat-is-not-the-future-interface-its-the-future-router#appendix\" class=\"hash-link\" aria-label=\"Direct link to Appendix\" title=\"Direct link to Appendix\">​</a></h2>\n<p align=\"center\"><img width=\"800\" src=\"https://didierlopes.com/blog/2026-01-20-chat-is-not-the-future-interface_6.webp\" alt=\"Apps in ChatGPT announcement\"></p>\n<br>\n<p>And a highly relevant post I read with the exact same idea I share in this thread:</p>\n<p align=\"center\"><img width=\"800\" src=\"https://didierlopes.com/blog/2026-01-20-chat-is-not-the-future-interface_7.webp\" alt=\"Related post about chat as router\"></p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/chat-is-not-the-future-interface-its-the-future-router",
            "title": "Chat is not the future interface. It's the future router.",
            "summary": "Why AI won't replace your apps, but your home screen",
            "date_modified": "2026-01-20T00:00:00.000Z",
            "tags": [
                "ai",
                "user-interface",
                "chatbots",
                "product"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/im-scared",
            "content_html": "<p>I shipped a working app in 15 minutes by rambling at Claude, and that's not the scary part.</p>\n<p>A few months ago, Dario Amodei said we might not need developers in 3-6 months.</p>\n<p>I thought that was far-fetched.</p>\n<p><strong>I don't anymore.</strong></p>\n<p>At least not directionally.</p>\n<p>I put together a demo to show where we're at. Not because the project itself matters - it's a dumb little site that counts how many words an AI uses to describe an image (you know, \"a picture is worth a thousand words\").</p>\n<p>What matters is <strong>how I built it</strong>.</p>\n<p>I talked to Claude for ~15 minutes. Voice-to-text rambling about what I wanted. It asked a few clarifying questions. Then I told it to go build it, commit after each step, and use the browser to test until it works.</p>\n<p>It one-shot the entire thing. React app. Deployed to GitHub Pages. Working.</p>\n<div class=\"flex place-items-center justify-center items-center rounded-sm mx-auto\"><iframe src=\"https://www.youtube.com/embed/T5PioWRvJeU\" width=\"800\" height=\"400\"></iframe></div>\n<br>\n<p>In this video I also talk about: how I speak to the terminal (and it speaks back, although I fixed that aha!); how skills are incredibly powerful primitives (better than MCPs!); how we close the feedback loop with agent controlling the browser; how agents writes tests that itself understands that they would pass - all this while going from vision to <a href=\"https://didierrlopes.github.io/is-this-image-worth-a-thousand-words/\" target=\"_blank\" rel=\"noopener noreferrer\">deployed project</a> in 15 minutes.</p>\n<p align=\"center\"><img width=\"800\" src=\"https://didierlopes.com/blog/2026-01-17-im-scared_1.webp\" alt=\"Screenshot of Dario Amodei quote\"></p>\n<br>\n<p>Here's what I keep thinking about:</p>\n<p>We spent millions of dollars and years building the OpenBB workspace. Nailing the UI/UX. Speed optimizations. Infrastructure choices. Iterating on product vision.</p>\n<p>But now? There's nothing stopping someone from opening our workspace, having Claude running on the side, and saying:</p>\n<blockquote>\n<p>\"Do not leave this session until you can replicate this product exactly 1:1.\"</p>\n</blockquote>\n<br>\n<p>This doesn't require our code being open source.</p>\n<p>This doesn't even require product vision - just the ability to see the product and iterate.</p>\n<p>And tokens are so freaking cheap.</p>\n<p>I think we're about to see a massive consolidation phase inside large organizations. When building apps becomes this easy, every department starts shipping their own tools. Same data, different outputs. Paying 3x for the same feeds. Teams duplicating work they don't even know exists elsewhere.</p>\n<p>That chaos creates real opportunity for platforms that unify the mess.</p>\n<p><strong>But!</strong></p>\n<p>When anyone can replicate a product by just <em>looking</em> at it, then the question becomes which products I want to build in-house (maintain) vs buy? It maybe starts becoming more about betting on a strong founder and team rather than the product, when deciding to buy.</p>\n<p>You're betting on character, authenticity and building true relationships.</p>\n<p>Maybe the things that our digital twins won't be able to touch for a while.</p>\n<p>In any case, things are about to become very weird.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/im-scared",
            "title": "I'm scared",
            "summary": "I shipped a working app in 15 minutes by rambling at Claude, and that's not the scary part.",
            "date_modified": "2026-01-17T00:00:00.000Z",
            "tags": [
                "ai",
                "claude",
                "agents",
                "software-development"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/joining-c-more-as-an-advisor",
            "content_html": "<p>I dedicate all my time to OpenBB. But when <a href=\"https://www.linkedin.com/in/carolinamalmeidacruz/\" target=\"_blank\" rel=\"noopener noreferrer\">Carolina</a> and <a href=\"https://www.linkedin.com/in/oscar-garcia-cabeza-bb0a9a/\" target=\"_blank\" rel=\"noopener noreferrer\">Oscar</a> showed me what they were building at <a href=\"https://cmore-sustainability.com/\" target=\"_blank\" rel=\"noopener noreferrer\">C-MORE</a> - verified ESG data meets AI - and we started collaborating informally, formalizing it as an advisor role was the obvious next step.</p>\n<p align=\"center\"><img width=\"800\" src=\"https://didierlopes.com/blog/2026-01-12-joining-c-more-as-an-advisor.webp\" alt=\"C-MORE advisory announcement\"></p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"background\">Background<a href=\"https://didierlopes.com/blog/joining-c-more-as-an-advisor#background\" class=\"hash-link\" aria-label=\"Direct link to Background\" title=\"Direct link to Background\">​</a></h2>\n<p>I've been hands-on with AI and machine learning since 2016, when I first applied Neural Networks to control systems in university. Since then, I've stayed close to the intersection of data, AI, and finance - implementing LSTM networks for financial time series forecasting (<a href=\"https://didierlopes.com/blog/an-unusual-journey-learning-about-nns-for-a-phd-thesis\">open-sourced here</a>), and more recently fine-tuning small language models running locally (<a href=\"https://didierlopes.com/blog/fine-tuning-a-llm-on-my-blog-posts\">detailed here</a>).</p>\n<p>At OpenBB, we've built an AI agent that helps analysts interact with any data in the workspace. I've learned firsthand what it takes to make AI systems trustworthy: clean data, traceable reasoning, and evidence-based outputs.</p>\n<p>Last year, I met Carolina and Oscar from C-MORE. Carolina is pursuing a PhD in Sustainability, Oscar brings deep Corporate Finance experience, and together they weren't just running a profitable, fast-growing company - they were getting their hands dirty with AI to out-innovate their competition.</p>\n<p>We connected immediately. We're from Portugal and Spain, share similar values about building, and think long-term. And <a href=\"https://www.linkedin.com/in/carinaabreu/\" target=\"_blank\" rel=\"noopener noreferrer\">Carina</a>, their co-founder, is actually from my hometown in Portugal (my quarterly reminder of how small the world is).</p>\n<p>We started collaborating informally. We held discussions regarding approaches for parsing complex documents with Gemini's long-context models. We talked through their AI strategy. The conversations kept getting deeper.</p>\n<p>Eventually, they asked to formalize the relationship. For me, it was a no-brainer - we were already working together, just without the paperwork.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"why-c-more\">Why C-MORE<a href=\"https://didierlopes.com/blog/joining-c-more-as-an-advisor#why-c-more\" class=\"hash-link\" aria-label=\"Direct link to Why C-MORE\" title=\"Direct link to Why C-MORE\">​</a></h2>\n<p>C-MORE is building one of the most advanced platforms in the world for operational risk and sustainability management.</p>\n<p>They automate ESG data collection, cleaning, and analysis - transforming how companies understand and improve their environmental and social performance. Their software is already trusted by 100+ clients across finance, real estate, energy, and supply chain management.</p>\n<p>But here's what matters: their data is verified by SGS, ensuring audit-ready quality. In a space where data integrity is everything, this is a massive differentiator.</p>\n<p>C-MORE's mission is to use automation and intelligence to create a more efficient, transparent, and sustainable future. And I'm a believer in the team executing on it.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"strong-foundation\">Strong foundation<a href=\"https://didierlopes.com/blog/joining-c-more-as-an-advisor#strong-foundation\" class=\"hash-link\" aria-label=\"Direct link to Strong foundation\" title=\"Direct link to Strong foundation\">​</a></h2>\n<p>If there's one thing I've learned building AI systems, it's this: data is everything. Specifically, data that's clean, structured, and verified - exactly what C-MORE has spent years building.</p>\n<p>Their data pipelines and collection processes are second to none. Over the past months, I've been helping the team think through their AI strategy - shaping how they approach evidence-based, traceable ESG answers.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"why-now\">Why now<a href=\"https://didierlopes.com/blog/joining-c-more-as-an-advisor#why-now\" class=\"hash-link\" aria-label=\"Direct link to Why now\" title=\"Direct link to Why now\">​</a></h2>\n<p>The timing couldn't be better.</p>\n<p>Regulatory frameworks like CSRD, CSDDD, and the EU Taxonomy are making ESG transparency mandatory. Investors are demanding verifiable data. Companies are under pressure to prove, not just promise, their impact, and to do so without exposing themselves to financial or reputational risk.</p>\n<p>Most ESG and operational-risk workflows today remain manual, fragmented, and costly - trapped in spreadsheets and endless verification loops.</p>\n<p>C-MORE changes that.</p>\n<p>Their platform doesn't just automate ESG reporting; it provides a secure data foundation that helps organizations protect and preserve their value. By centralizing and validating ESG and risk data, C-MORE enables firms to anticipate exposure before it becomes a headline.</p>\n<p>And they're moving fast.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"how-this-ties-to-openbb\">How this ties to OpenBB<a href=\"https://didierlopes.com/blog/joining-c-more-as-an-advisor#how-this-ties-to-openbb\" class=\"hash-link\" aria-label=\"Direct link to How this ties to OpenBB\" title=\"Direct link to How this ties to OpenBB\">​</a></h2>\n<p>This is directly relevant.</p>\n<p>Once you have high-quality data and a reliable AI layer, the next challenge is delivery - how you make it accessible, useful, and intuitive for end users.</p>\n<p>Advising C-MORE gives me insight into how enterprise data vendors think about that last mile. We already have community members building apps in the OpenBB workspace and sharing them, but I see an opportunity at the enterprise level: enabling vendors to take our interface and own it with their branding.</p>\n<p>We already have the enterprise features - user access controls, role-based permissions, app management, shared dashboards. And we let users connect data to AI agents in an AI-first workspace.</p>\n<p>My recent conversations with Oscar have been nothing short of exciting.</p>\n<p><strong>The first AI-native ESG Terminal may not be too far.</strong></p>\n<p>Imagine C-MORE's verified, structured ESG data and AI agents wrapped in OpenBB's open, modular interface built for analysts and investors. I think we can offer their users an experience second to none.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"looking-ahead\">Looking ahead<a href=\"https://didierlopes.com/blog/joining-c-more-as-an-advisor#looking-ahead\" class=\"hash-link\" aria-label=\"Direct link to Looking ahead\" title=\"Direct link to Looking ahead\">​</a></h2>\n<p>Advising C-MORE gives me insight into what it takes to build a large-scale data business with purpose. It's a chance to learn from a team solving hard problems - and to help shape how AI can make complex data transparent, actionable, and impactful.</p>\n<p>C-MORE is only getting started, but the trajectory is clear: the next generation of ESG intelligence will be built by those who combine clean data, strong AI, and beautiful interfaces loved by customers.</p>\n<p>I'm excited about this side quest.</p>\n<p>If you're dealing with ESG compliance, looking for better sustainability data infrastructure, or just curious about what C-MORE is building - reach out. I'm happy to share more or make introductions to the team.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/joining-c-more-as-an-advisor",
            "title": "Joining C-MORE as an advisor",
            "summary": "I dedicate all my time to OpenBB. But when Carolina and Oscar showed me what they were building at C-MORE - verified ESG data meets AI - formalizing it as an advisor role was the obvious next step.",
            "date_modified": "2026-01-12T00:00:00.000Z",
            "tags": [
                "advisory",
                "esg",
                "sustainability",
                "ai",
                "openbb"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/building-a-pokemon-card-price-estimator-with-claude-code",
            "content_html": "<p>The Pokemon TCG market is inefficient. I built a tool to exploit it.</p>\n<p>A few weeks ago, I saw this post on X.</p>\n<p>That post reminded me of my childhood, where I had a few sets of Pokemon cards. However, silly me, I sold all of those sets a few years ago when I was back home. I didn't even think that much about it to be honest.</p>\n<p>Then I talked about it with my wife, and she shared a Pokemon pop-up happening in NYC.</p>\n<p>When we were in Chelsea Market with friends visiting from out of town, we stopped by. I looked for a Kabuto card - specifically the Gen 1 version - but couldn't find it. So I grabbed the Gen 2 version instead, just in case.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2026-01-06-building-a-pokemon-card-price-estimator-with-claude-code_1.webp\" alt=\"Kabuto card purchase\"></p>\n<p>And then I bought a booster pack. You know, just in case.</p>\n<p>I got home and opened it. Eleven cards stared back at me. But I had no idea what any of them were worth.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2026-01-06-building-a-pokemon-card-price-estimator-with-claude-code_2.webp\" alt=\"Booster pack cards\"></p>\n<p>My first instinct was to take a photo and throw it at ChatGPT: \"How much are these worth?\"</p>\n<p>The results were... bad. The model would either not respond or confuse cards, miss some or even hallucinate prices.</p>\n<p>I was giving it way too much freedom. Without constraints, the model didn't know where to pull reliable information from. It would make up prices or reference outdated data or just plain ignore the card.</p>\n<p>But anyway, after a bit of chat it was enough for me to understand that what I got sucked. So I went into eBay to see if there were good cards for sale - you know, as a \"store of value\".</p>\n<p>And of course, pictures on eBay are diabolical.</p>\n<p>And maybe, just maybe, there were sellers that were as clueless as I was selling Pokemon cards back a few years.</p>\n<p>But I just didn't know how to value the cards from a picture. So I couldn't know if a set listed for $20 was worth $10 or $100.</p>\n<p>But I knew who could.</p>\n<p>The combined information from the web and a specific skillset - <strong>ENTER CLAUDE SKILLS</strong>.</p>\n<p>So I built a Claude Code skill that does exactly that.</p>\n<p>The full source code is available on <a href=\"https://github.com/DidierRLopes/pokemon-cards-value-scraper\" target=\"_blank\" rel=\"noopener noreferrer\">GitHub</a>.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"the-workflow\">The workflow<a href=\"https://didierlopes.com/blog/building-a-pokemon-card-price-estimator-with-claude-code#the-workflow\" class=\"hash-link\" aria-label=\"Direct link to The workflow\" title=\"Direct link to The workflow\">​</a></h2>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"step-0-find-a-set-that-you-might-be-interested-in\">Step 0: Find a set that you might be interested in<a href=\"https://didierlopes.com/blog/building-a-pokemon-card-price-estimator-with-claude-code#step-0-find-a-set-that-you-might-be-interested-in\" class=\"hash-link\" aria-label=\"Direct link to Step 0: Find a set that you might be interested in\" title=\"Direct link to Step 0: Find a set that you might be interested in\">​</a></h3>\n<p align=\"center\"><img width=\"800\" src=\"https://didierlopes.com/blog/2026-01-06-building-a-pokemon-card-price-estimator-with-claude-code_3.webp\" alt=\"eBay Pokemon card listing\"></p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"step-1-provide-an-image\">Step 1: Provide an Image<a href=\"https://didierlopes.com/blog/building-a-pokemon-card-price-estimator-with-claude-code#step-1-provide-an-image\" class=\"hash-link\" aria-label=\"Direct link to Step 1: Provide an Image\" title=\"Direct link to Step 1: Provide an Image\">​</a></h3>\n<p>Drop a photo of Pokemon cards - a binder page, a spread on a table, whatever.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2026-01-06-building-a-pokemon-card-price-estimator-with-claude-code_4.webp\" alt=\"Test Pokemon cards input\"></p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"step-2-card-recognition\">Step 2: Card Recognition<a href=\"https://didierlopes.com/blog/building-a-pokemon-card-price-estimator-with-claude-code#step-2-card-recognition\" class=\"hash-link\" aria-label=\"Direct link to Step 2: Card Recognition\" title=\"Direct link to Step 2: Card Recognition\">​</a></h3>\n<p>Claude's vision model analyzes the image and extracts card details into a structured table:</p>\n<table><thead><tr><th>#</th><th>Name</th><th>Set</th><th>Card #</th><th>Holo</th><th>Edition</th></tr></thead><tbody><tr><td>1</td><td>Alakazam</td><td>Base Set</td><td>1/102</td><td>Holo</td><td>Unlimited</td></tr><tr><td>2</td><td>Blastoise</td><td>Base Set</td><td>2/102</td><td>Holo</td><td>Unlimited</td></tr><tr><td>3</td><td>Charizard</td><td>Base Set</td><td>4/102</td><td>Holo</td><td>Unlimited</td></tr></tbody></table>\n<br>\n<p>The key here is providing clear guidelines about what to look for (set symbols, card numbers, holo patterns) and what to ignore (partially visible cards, reflections). Without these constraints, the model hallucinates. With them, it's remarkably accurate. And if in doubt, the model will ask to clarify.</p>\n<p align=\"center\"><img width=\"800\" src=\"https://didierlopes.com/blog/2026-01-06-building-a-pokemon-card-price-estimator-with-claude-code_5.webp\" alt=\"Card recognition in Claude Code\"></p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"step-3-human-in-the-loop-confirmation\">Step 3: Human-in-the-Loop Confirmation<a href=\"https://didierlopes.com/blog/building-a-pokemon-card-price-estimator-with-claude-code#step-3-human-in-the-loop-confirmation\" class=\"hash-link\" aria-label=\"Direct link to Step 3: Human-in-the-Loop Confirmation\" title=\"Direct link to Step 3: Human-in-the-Loop Confirmation\">​</a></h3>\n<p>Even if the model was confident on the cards, it can still misread card numbers or confuse similar-looking Pokemon. A quick sanity check saves headaches later.</p>\n<p>So this just allows you to iterate quickly. E.g. if you see that it got the wrong Pokemon, or that the card is not a Holo you can quickly rectify it here.</p>\n<p>Once this is confirmed we export this as a raw CSV file.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"step-4-visual-verification-grid\">Step 4: Visual Verification Grid<a href=\"https://didierlopes.com/blog/building-a-pokemon-card-price-estimator-with-claude-code#step-4-visual-verification-grid\" class=\"hash-link\" aria-label=\"Direct link to Step 4: Visual Verification Grid\" title=\"Direct link to Step 4: Visual Verification Grid\">​</a></h3>\n<p>Here's where it gets interesting.</p>\n<p>Claude Code downloads the official card image for each identified card from <a href=\"https://pokemontcg.io/\" target=\"_blank\" rel=\"noopener noreferrer\">pokemontcg.io</a>. To do this, we need to map set names to their API codes - \"Base Set\" → base1, \"Twilight Masquerade\" → sv6.</p>\n<p>I built a lookup table covering 100+ sets from 1999 to 2025.</p>\n<p>Then we use PIL (Pillow) to reconstruct the original layout - same rows, same columns. For instance <code>--layout 3,3,3</code> flag means 3 cards per row, 3 rows total.</p>\n<p>We added this script to this specific SKILLS folder.</p>\n<p align=\"center\"><img width=\"800\" src=\"https://didierlopes.com/blog/2026-01-06-building-a-pokemon-card-price-estimator-with-claude-code_6.webp\" alt=\"Visual verification script in Claude Code\"></p>\n<p>I store images from each of the cards individually. But most importantly I reconstruct the layout so it's easy to compare with my eyes. Here's the resulting output:</p>\n<p align=\"center\"><img width=\"800\" src=\"https://didierlopes.com/blog/2026-01-06-building-a-pokemon-card-price-estimator-with-claude-code_7.webp\" alt=\"Reconstructed card layout for verification\"></p>\n<p>As they match, I'm confident in the identification. If something's off, I go back and fix the table before wasting time on wrong price lookups.</p>\n<p>Why bother with this step? Two reasons:</p>\n<ol>\n<li>\n<p><strong>Image quality varies wildly.</strong> eBay photos are particularly bad - poor lighting, weird angles, reflections everywhere. The verification grid catches misidentifications before they become wrong prices.</p>\n</li>\n<li>\n<p><strong>Holos are hard.</strong> Distinguishing between a regular card, a holo, and a reverse holo from a photo is genuinely difficult. The rainbow sheen doesn't always photograph well. Human verification catches these edge cases.</p>\n</li>\n</ol>\n<br>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"step-5-price-estimation\">Step 5: Price Estimation<a href=\"https://didierlopes.com/blog/building-a-pokemon-card-price-estimator-with-claude-code#step-5-price-estimation\" class=\"hash-link\" aria-label=\"Direct link to Step 5: Price Estimation\" title=\"Direct link to Step 5: Price Estimation\">​</a></h3>\n<p>With double-verified card data, Claude Code fetches prices from <a href=\"https://pokellector.com/\" target=\"_blank\" rel=\"noopener noreferrer\">Pokellector.com</a>, which aggregates six sources:</p>\n<ul>\n<li>TCGPlayer</li>\n<li>Troll &amp; Toad</li>\n<li>eBay</li>\n<li>Stop2Shop</li>\n<li>Collectors Cache</li>\n<li>CoolStuffInc</li>\n</ul>\n<br>\n<p>We have another script file on our SKILLS folder that is responsible by this.</p>\n<p>Here's the catch: Pokellector is renders dynamically with JavaScript, so requests and BeautifulSoup alone didn't work. So I had to use Selenium with headless Chrome to:</p>\n<ol>\n<li>Search for a card</li>\n<li>Navigate to the best match</li>\n<li>Extract prices from all six sources</li>\n<li>Capture reference URLs</li>\n</ol>\n<br>\n<p>The result: a comprehensive price table with links to verify each price.</p>\n<p align=\"center\"><img width=\"800\" src=\"https://didierlopes.com/blog/2026-01-06-building-a-pokemon-card-price-estimator-with-claude-code_8.webp\" alt=\"Price estimation results\"></p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"the-takeaway\">The Takeaway<a href=\"https://didierlopes.com/blog/building-a-pokemon-card-price-estimator-with-claude-code#the-takeaway\" class=\"hash-link\" aria-label=\"Direct link to The Takeaway\" title=\"Direct link to The Takeaway\">​</a></h2>\n<p>Throwing an image at a model and asking \"what's this worth?\" gives you unreliable results. But breaking the problem into discrete steps, adding human verification at key points, and constraining the model's data sources transforms it into something genuinely useful.</p>\n<p>Ultimately, it boils down to \"do you have this skillset?\".</p>\n<p>And now you add skills easily to your agents.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"whats-next\">What's Next<a href=\"https://didierlopes.com/blog/building-a-pokemon-card-price-estimator-with-claude-code#whats-next\" class=\"hash-link\" aria-label=\"Direct link to What's Next\" title=\"Direct link to What's Next\">​</a></h2>\n<p>A few ideas of what could be done:</p>\n<ul>\n<li>\n<p><strong>eBay URL scraping:</strong> Instead of manually saving photos, provide an eBay listing URL. The tool would scrape the images, run the identification workflow, and tell you if the listing is underpriced.</p>\n</li>\n<li>\n<p><strong>Interface:</strong> Right now this runs as a Claude Code skill. A dedicated website with lower latency and a cleaner UX would make it more accessible.</p>\n</li>\n<li>\n<p><strong>Batch processing:</strong> For larger collections, process multiple binder pages in sequence and aggregate the results.</p>\n</li>\n<li>\n<p><strong>Condition grading:</strong> Card condition dramatically affects value. Integrating some form of condition assessment (even a rough one) would improve accuracy.</p>\n</li>\n</ul><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/building-a-pokemon-card-price-estimator-with-claude-code",
            "title": "Building a Pokemon Card Price Estimator with Claude Code",
            "summary": "The Pokemon TCG market is inefficient. I built a tool to exploit it.",
            "date_modified": "2026-01-06T00:00:00.000Z",
            "tags": [
                "pokemon",
                "claude-code",
                "ai",
                "automation"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/podcast-takeover",
            "content_html": "<p>A list of my favorite podcasts from 2025.</p>\n<p>For the last couple of years I've been reading more and more books...</p>\n<p align=\"center\"><img width=\"800\" src=\"https://didierlopes.com/blog/2025-12-30-podcast-takeover_1.webp\" alt=\"Books tracking screenshot\"></p>\n<p>I keep track of my books read (and to read) in my website <a href=\"https://didierlopes.com/books/already-read\">here</a>.</p>\n<p>Recently though, I've spent a great deal of time listening to podcasts.</p>\n<p>I used to say I preferred books because they take months to produce, and by the time someone recommends one to me, there are thousands of reviews on it. So in a way, a book is not only carefully reviewed by the publisher but also vetted by thousands of readers.</p>\n<p>Another thing: most books I read, startup stories, founder biographies, culture, ways of living, are timeless. If I read them today or in 10 years, they're just as valuable. This is a feature. It's also why authors spend so much time writing them in the first place. They know the ideas will echo for years to come.</p>\n<p>Podcasts, on the other hand, are a thing of the moment. Hosts don't think as heavily about what they say, at least not to the extent authors do with a book.</p>\n<p>But with that comes a more unfiltered glimpse of personality. You also get nuggets of wisdom that are actually relevant <em>right now</em>, since most podcasts I listen to are about the current state of the world.</p>\n<p>Think of it as a simple 2x2: Is the topic timeless or timely? Has it already been deeply examined, or is it still unfolding? Books win for the former. Podcasts win for the latter.</p>\n<p>So there are merits in both, and as a result I've been enjoying spending a lot of time in podcasts.</p>\n<p>With that said, I've listened to over 20 different podcasts and while I don't religiously consume one in particular (ok, I do that with Acquired) - I tend to see them based on the episodes that get more traction on social media and my mood tbh.</p>\n<p>Here's my list of favorites (and a recommended episode on each), with some organization:</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"1-strategy-business-models--markets\">1. Strategy, Business Models &amp; Markets<a href=\"https://didierlopes.com/blog/podcast-takeover#1-strategy-business-models--markets\" class=\"hash-link\" aria-label=\"Direct link to 1. Strategy, Business Models &amp; Markets\" title=\"Direct link to 1. Strategy, Business Models &amp; Markets\">​</a></h2>\n<p>Company breakdowns, investing frameworks, market structure.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"acquired\">Acquired<a href=\"https://didierlopes.com/blog/podcast-takeover#acquired\" class=\"hash-link\" aria-label=\"Direct link to Acquired\" title=\"Direct link to Acquired\">​</a></h3>\n<p>Long-form, documentary-style deep dives into iconic companies and business stories. Ben and David do real research, real narrative, and episodes that feel like MBA case studies but actually interesting.</p>\n<div class=\"flex place-items-center justify-center items-center rounded-sm mx-auto\"><iframe src=\"https://www.youtube.com/embed/A0fvX-wV70Y\" width=\"800\" height=\"400\"></iframe></div>\n<br>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"founders\">Founders<a href=\"https://didierlopes.com/blog/podcast-takeover#founders\" class=\"hash-link\" aria-label=\"Direct link to Founders\" title=\"Direct link to Founders\">​</a></h3>\n<p>David Senra reads biographies of history's greatest founders and distills the lessons, patterns, and psychology behind how they built. It's basically getting the highlights of 50+ years of experience from people who've done impossible things - compressed into an episode you can listen to on a walk.</p>\n<div class=\"flex place-items-center justify-center items-center rounded-sm mx-auto\"><iframe src=\"https://www.youtube.com/embed/aStHTTPxlis\" width=\"800\" height=\"400\"></iframe></div>\n<br>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"invest-like-the-best\">Invest Like the Best<a href=\"https://didierlopes.com/blog/podcast-takeover#invest-like-the-best\" class=\"hash-link\" aria-label=\"Direct link to Invest Like the Best\" title=\"Direct link to Invest Like the Best\">​</a></h3>\n<p>Patrick O'Shaughnessy interviews world-class investors across hedge funds, quants, PE, and more. Pure frameworks and mental models - no filler, no motivational fluff.</p>\n<div class=\"flex place-items-center justify-center items-center rounded-sm mx-auto\"><iframe src=\"https://www.youtube.com/embed/g4zzkuFyI18\" width=\"800\" height=\"400\"></iframe></div>\n<br>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"in-good-company\">In Good Company<a href=\"https://didierlopes.com/blog/podcast-takeover#in-good-company\" class=\"hash-link\" aria-label=\"Direct link to In Good Company\" title=\"Direct link to In Good Company\">​</a></h3>\n<p>Hosted by Nicolai Tangen, CEO of the Norwegian Sovereign Wealth Fund (the largest investor on earth). Surprisingly candid conversations with practitioners from the financial world who almost never do long interviews.</p>\n<div class=\"flex place-items-center justify-center items-center rounded-sm mx-auto\"><iframe src=\"https://www.youtube.com/embed/zRkNO9yNYoI\" width=\"800\" height=\"400\"></iframe></div>\n<br>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"jordi-visser\">Jordi Visser<a href=\"https://didierlopes.com/blog/podcast-takeover#jordi-visser\" class=\"hash-link\" aria-label=\"Direct link to Jordi Visser\" title=\"Direct link to Jordi Visser\">​</a></h3>\n<p>Jordi Visser (ex-CIO of Weiss Multi-Strategy) runs one of the few market podcasts that actually talks about the current markets. He blends macro, data, sentiment, and real trading intuition in a way that's easy to follow but still useful if you're deep in markets. Extremely high signal. And he uses OpenBB.</p>\n<div class=\"flex place-items-center justify-center items-center rounded-sm mx-auto\"><iframe src=\"https://www.youtube.com/embed/3CvQ7YfOSQs\" width=\"800\" height=\"400\"></iframe></div>\n<br>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"2-ai-focused\">2. AI-Focused<a href=\"https://didierlopes.com/blog/podcast-takeover#2-ai-focused\" class=\"hash-link\" aria-label=\"Direct link to 2. AI-Focused\" title=\"Direct link to 2. AI-Focused\">​</a></h2>\n<p>Deep AI conversations: safety, scaling laws, model design, applied AI strategy.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"dwarkesh-patel\">Dwarkesh Patel<a href=\"https://didierlopes.com/blog/podcast-takeover#dwarkesh-patel\" class=\"hash-link\" aria-label=\"Direct link to Dwarkesh Patel\" title=\"Direct link to Dwarkesh Patel\">​</a></h3>\n<p>Dwarkesh is one of the clearest, most rigorous thinkers in AI today, and he interviews people operating at the absolute frontier. His conversations aren't surface-level - they cut into alignment, frontier model design, geopolitics, scientific breakthroughs, and the real engineering that actually moves the field forward.</p>\n<div class=\"flex place-items-center justify-center items-center rounded-sm mx-auto\"><iframe src=\"https://www.youtube.com/embed/lXUZvyajciY\" width=\"800\" height=\"400\"></iframe></div>\n<br>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"no-priors\">No Priors<a href=\"https://didierlopes.com/blog/podcast-takeover#no-priors\" class=\"hash-link\" aria-label=\"Direct link to No Priors\" title=\"Direct link to No Priors\">​</a></h3>\n<p>Sarah Guo and Elad Gil talk to AI founders, researchers, and investors about the realities of building and scaling AI-native products. Practical, technical, and grounded.</p>\n<div class=\"flex place-items-center justify-center items-center rounded-sm mx-auto\"><iframe src=\"https://www.youtube.com/embed/UIDMhKgpqkg\" width=\"800\" height=\"400\"></iframe></div>\n<br>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"every\">Every<a href=\"https://didierlopes.com/blog/podcast-takeover#every\" class=\"hash-link\" aria-label=\"Direct link to Every\" title=\"Direct link to Every\">​</a></h3>\n<p>A media outfit led by Dan Shipper (co-founder &amp; CEO of Every). Every publishes a daily newsletter and runs the podcast AI &amp; I, where Dan has in-depth conversations with builders, creators, and thinkers about how they use AI and tools to build, create, and organize. Worth tuning in for unfiltered takes on the future of work, AI culture, and creator workflows.</p>\n<div class=\"flex place-items-center justify-center items-center rounded-sm mx-auto\"><iframe src=\"https://www.youtube.com/embed/7SPHYmlkGMY\" width=\"800\" height=\"400\"></iframe></div>\n<br>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"the-hedgineer-podcast\">The Hedgineer Podcast<a href=\"https://didierlopes.com/blog/podcast-takeover#the-hedgineer-podcast\" class=\"hash-link\" aria-label=\"Direct link to The Hedgineer Podcast\" title=\"Direct link to The Hedgineer Podcast\">​</a></h3>\n<p>Hosted by Michael Watson - former Citadel MD turned engineer-interpreter of markets and tech. The show dives into how hedge funds, prop-trading shops, and modern asset managers build with data, AI, and engineering - recent episodes explore alt-data, ML-driven research, and trading-infra design. Great if you want the engineering + quant lens on finance.</p>\n<div class=\"flex place-items-center justify-center items-center rounded-sm mx-auto\"><iframe src=\"https://www.youtube.com/embed/VVBZjF1nM08\" width=\"800\" height=\"400\"></iframe></div>\n<br>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"3-technology--engineering\">3. Technology &amp; Engineering<a href=\"https://didierlopes.com/blog/podcast-takeover#3-technology--engineering\" class=\"hash-link\" aria-label=\"Direct link to 3. Technology &amp; Engineering\" title=\"Direct link to 3. Technology &amp; Engineering\">​</a></h2>\n<p>Software engineering, infrastructure, dev culture, technical founders.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"bg2-pod\">Bg2 Pod<a href=\"https://didierlopes.com/blog/podcast-takeover#bg2-pod\" class=\"hash-link\" aria-label=\"Direct link to Bg2 Pod\" title=\"Direct link to Bg2 Pod\">​</a></h3>\n<p>Hosted by Brad Gerstner (founder &amp; CEO of Altimeter) and Bill Gurley (legendary former Benchmark GP), BG2 is an \"open-source\" bi-weekly conversation on tech, markets, investing, and capitalism - basically two top-tier public markets/VC minds thinking out loud about how the world is changing.</p>\n<div class=\"flex place-items-center justify-center items-center rounded-sm mx-auto\"><iframe src=\"https://www.youtube.com/embed/pE6sw_E9Gh0\" width=\"800\" height=\"400\"></iframe></div>\n<br>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"ycombinator\">YCombinator<a href=\"https://didierlopes.com/blog/podcast-takeover#ycombinator\" class=\"hash-link\" aria-label=\"Direct link to YCombinator\" title=\"Direct link to YCombinator\">​</a></h3>\n<p>Run by YC partners, this is YC pulling back the curtain: founder interviews, office hours, and very blunt advice on building, launching, and scaling startups. It's basically YC's playbook, but in audio form.</p>\n<div class=\"flex place-items-center justify-center items-center rounded-sm mx-auto\"><iframe src=\"https://www.youtube.com/embed/Zyw-YA0k3xo\" width=\"800\" height=\"400\"></iframe></div>\n<br>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"the-pragmatic-engineer\">The Pragmatic Engineer<a href=\"https://didierlopes.com/blog/podcast-takeover#the-pragmatic-engineer\" class=\"hash-link\" aria-label=\"Direct link to The Pragmatic Engineer\" title=\"Direct link to The Pragmatic Engineer\">​</a></h3>\n<p>Hosted by Gergely Orosz - ex-Uber engineering leader and author of the #1 tech newsletter on Substack. It's deep dives into how software is actually built and run at big tech and high-growth startups: real org design, real incidents, real trade-offs from people who've been in the room.</p>\n<div class=\"flex place-items-center justify-center items-center rounded-sm mx-auto\"><iframe src=\"https://www.youtube.com/embed/98o_L3jlixw\" width=\"800\" height=\"400\"></iframe></div>\n<br>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"4-builders-operators--product-thinking\">4. Builders, Operators &amp; Product Thinking<a href=\"https://didierlopes.com/blog/podcast-takeover#4-builders-operators--product-thinking\" class=\"hash-link\" aria-label=\"Direct link to 4. Builders, Operators &amp; Product Thinking\" title=\"Direct link to 4. Builders, Operators &amp; Product Thinking\">​</a></h2>\n<p>Founders, operators, product leaders — how things get built and scaled.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"sourcery\">Sourcery<a href=\"https://didierlopes.com/blog/podcast-takeover#sourcery\" class=\"hash-link\" aria-label=\"Direct link to Sourcery\" title=\"Direct link to Sourcery\">​</a></h3>\n<p>Hosted by Molly O'Shea. The podcast interviews top investors, founders, and CEOs about how tech, markets and capital are evolving. It's smart, sharp, and gives insider-level POV on what's really happening in fintech, AI, and venture.</p>\n<div class=\"flex place-items-center justify-center items-center rounded-sm mx-auto\"><iframe src=\"https://www.youtube.com/embed/sLlmQoCZe2A\" width=\"800\" height=\"400\"></iframe></div>\n<br>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"uncapped-with-jack-altman\">Uncapped with Jack Altman<a href=\"https://didierlopes.com/blog/podcast-takeover#uncapped-with-jack-altman\" class=\"hash-link\" aria-label=\"Direct link to Uncapped with Jack Altman\" title=\"Direct link to Uncapped with Jack Altman\">​</a></h3>\n<p>Hosted by Jack Altman (founder &amp; former CEO of Lattice), Uncapped is a sharp read on venture-building, scaling, and fundraising. It's conversations with founders and investors he respects - covering what actually works (and what doesn't) when you scale a company or back one.</p>\n<div class=\"flex place-items-center justify-center items-center rounded-sm mx-auto\"><iframe src=\"https://www.youtube.com/embed/mZUG0pr5hBo\" width=\"800\" height=\"400\"></iframe></div>\n<br>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"lennys-podcast\">Lenny's Podcast<a href=\"https://didierlopes.com/blog/podcast-takeover#lennys-podcast\" class=\"hash-link\" aria-label=\"Direct link to Lenny's Podcast\" title=\"Direct link to Lenny's Podcast\">​</a></h3>\n<p>While often positioned as a product/PM podcast, in 2025 Lenny has become a must-listen for builders. He's become the voice of fast-growing startups in my opinion.</p>\n<div class=\"flex place-items-center justify-center items-center rounded-sm mx-auto\"><iframe src=\"https://www.youtube.com/embed/En5cSXgGvZM\" width=\"800\" height=\"400\"></iframe></div>\n<br>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"cheeky-pint\">Cheeky Pint<a href=\"https://didierlopes.com/blog/podcast-takeover#cheeky-pint\" class=\"hash-link\" aria-label=\"Direct link to Cheeky Pint\" title=\"Direct link to Cheeky Pint\">​</a></h3>\n<p>Hosted by John Collison (co-founder of Stripe), Cheeky Pint is basically \"over a beer with builders and founders\" - honest, wide-ranging, and often unexpectedly insightful. He sits down with people shaping tech, markets, and infrastructure and gets them to speak plainly about their work and worldview.</p>\n<div class=\"flex place-items-center justify-center items-center rounded-sm mx-auto\"><iframe src=\"https://www.youtube.com/embed/GcqQ1ebBqkc\" width=\"800\" height=\"400\"></iframe></div>\n<br>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"starter-story\">Starter Story<a href=\"https://didierlopes.com/blog/podcast-takeover#starter-story\" class=\"hash-link\" aria-label=\"Direct link to Starter Story\" title=\"Direct link to Starter Story\">​</a></h3>\n<p>Founded by Pat Walls, Starter Story digs into how real-life entrepreneurs built their businesses from scratch - from niche SaaS to e-commerce. It's a no-fluff breakdown of what worked, what didn't, and exactly how people went from zero to a working business.</p>\n<div class=\"flex place-items-center justify-center items-center rounded-sm mx-auto\"><iframe src=\"https://www.youtube.com/embed/WGVxAmmJUmY\" width=\"800\" height=\"400\"></iframe></div>\n<br>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"library-of-minds\">Library of Minds<a href=\"https://didierlopes.com/blog/podcast-takeover#library-of-minds\" class=\"hash-link\" aria-label=\"Direct link to Library of Minds\" title=\"Direct link to Library of Minds\">​</a></h3>\n<p>A fresh podcast from Delphi that sits down with top founders, investors, and thinkers to unpack how they build, make decisions, and see the future.</p>\n<div class=\"flex place-items-center justify-center items-center rounded-sm mx-auto\"><iframe src=\"https://www.youtube.com/embed/RMOvO3tFntQ\" width=\"800\" height=\"400\"></iframe></div>\n<br>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"5-cultural--intellectual-conversation\">5. Cultural &amp; Intellectual Conversation<a href=\"https://didierlopes.com/blog/podcast-takeover#5-cultural--intellectual-conversation\" class=\"hash-link\" aria-label=\"Direct link to 5. Cultural &amp; Intellectual Conversation\" title=\"Direct link to 5. Cultural &amp; Intellectual Conversation\">​</a></h2>\n<p>Curiosity-driven conversations with thinkers, scientists, creators.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"lex-fridman-podcast\">Lex Fridman Podcast<a href=\"https://didierlopes.com/blog/podcast-takeover#lex-fridman-podcast\" class=\"hash-link\" aria-label=\"Direct link to Lex Fridman Podcast\" title=\"Direct link to Lex Fridman Podcast\">​</a></h3>\n<p>Lex runs long-form conversations with people who are actually interesting. A few hours of open space where he lets the guest think out loud - CEOs, politicians, scientists, founders, whoever. The big episodes get all the views, but the best ones are the niche conversations where someone brilliant has room to explain how they see the world.</p>\n<div class=\"flex place-items-center justify-center items-center rounded-sm mx-auto\"><iframe src=\"https://www.youtube.com/embed/oFtjKbXKqbg\" width=\"800\" height=\"400\"></iframe></div>\n<br>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"joe-rogan\">Joe Rogan<a href=\"https://didierlopes.com/blog/podcast-takeover#joe-rogan\" class=\"hash-link\" aria-label=\"Direct link to Joe Rogan\" title=\"Direct link to Joe Rogan\">​</a></h3>\n<p>Hosted by Joe Rogan, comedian and UFC commentator turned long-form interviewer. Unfiltered, unstructured conversations with scientists, fighters, authors, technologists, and random fascinating people.</p>\n<div class=\"flex place-items-center justify-center items-center rounded-sm mx-auto\"><iframe src=\"https://www.youtube.com/embed/WfmrEa0L08E\" width=\"800\" height=\"400\"></iframe></div>\n<br>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"not-a-regular-podcast\">Not a Regular Podcast<a href=\"https://didierlopes.com/blog/podcast-takeover#not-a-regular-podcast\" class=\"hash-link\" aria-label=\"Direct link to Not a Regular Podcast\" title=\"Direct link to Not a Regular Podcast\">​</a></h2>\n<p>These are not a podcast, but a series of videos that I come back to over and over!</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"ai-engineer\">AI Engineer<a href=\"https://didierlopes.com/blog/podcast-takeover#ai-engineer\" class=\"hash-link\" aria-label=\"Direct link to AI Engineer\" title=\"Direct link to AI Engineer\">​</a></h3>\n<p>AI Engineer is a media + events brand for AI builders, run by Swyx. They organize things like the AI Engineer Code Summit and World's Fair and publish talks, workshops, and training sessions specifically for people building with modern AI tools.</p>\n<div class=\"flex place-items-center justify-center items-center rounded-sm mx-auto\"><iframe src=\"https://www.youtube.com/embed/YpY83-kA7Bo\" width=\"800\" height=\"400\"></iframe></div>\n<br>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"jason-liu\">Jason Liu<a href=\"https://didierlopes.com/blog/podcast-takeover#jason-liu\" class=\"hash-link\" aria-label=\"Direct link to Jason Liu\" title=\"Direct link to Jason Liu\">​</a></h3>\n<p>Hosted by Jason Liu, AI researcher/engineer. Always brings strong guests from practitioners implementing real AI in fast growing startups. Big focus on RAG pipelines.</p>\n<div class=\"flex place-items-center justify-center items-center rounded-sm mx-auto\"><iframe src=\"https://www.youtube.com/embed/DS4w1CMGJes\" width=\"800\" height=\"400\"></iframe></div>\n<br>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"theo---t3gg\">Theo - t3.gg<a href=\"https://didierlopes.com/blog/podcast-takeover#theo---t3gg\" class=\"hash-link\" aria-label=\"Direct link to Theo - t3.gg\" title=\"Direct link to Theo - t3.gg\">​</a></h3>\n<p>Hosted by Theo, ex-Twitch engineer with strong opinions on dev tooling and full-stack engineering. Lately doing a lot of videos on AI models with his latest product.</p>\n<div class=\"flex place-items-center justify-center items-center rounded-sm mx-auto\"><iframe src=\"https://www.youtube.com/embed/39PdgOYjBMg\" width=\"800\" height=\"400\"></iframe></div>\n<br>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"tbpn\">TBPN<a href=\"https://didierlopes.com/blog/podcast-takeover#tbpn\" class=\"hash-link\" aria-label=\"Direct link to TBPN\" title=\"Direct link to TBPN\">​</a></h3>\n<p>TBPN (Technology Business Programming Network) is a daily live tech show hosted by John Coogan and Jordi Hays. It's basically SportsCenter for tech and AI - three hours a day of news, founder/VC interviews, and live reactions to what's happening in the industry.</p>\n<div class=\"flex place-items-center justify-center items-center rounded-sm mx-auto\"><iframe src=\"https://www.youtube.com/embed/R5KbGwY-zf0\" width=\"800\" height=\"400\"></iframe></div>\n<br>\n<p>I compiled this collection in an open source repo, so I can keep expanding as I listen to different ones. But also their RSS feeds so you can add them to your RSS readers if interested.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/podcast-takeover",
            "title": "Podcast takeover",
            "summary": "A list of my favorite podcasts from 2025.",
            "date_modified": "2025-12-30T00:00:00.000Z",
            "tags": [
                "podcasts",
                "learning",
                "recommendations"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/i-built-a-claude-skill-that-turns-podcasts-into-shareable-clips",
            "content_html": "<p><img decoding=\"async\" loading=\"lazy\" alt=\"I built a Claude Skill that turns podcasts into shareable clips\" src=\"https://didierlopes.com/assets/images/2025-12-22-i-built-a-claude-skill-that-turns-podcasts-into-shareable-clips-4c6e7f0bb2582269cd0c283c4519fd30.webp\" width=\"945\" height=\"630\" class=\"img_ev3q\"></p>\n<p>Skills might be the right abstraction for agentic workflows.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>I've been meaning to experiment with <a href=\"https://claude.com/blog/skills\" target=\"_blank\" rel=\"noopener noreferrer\">Claude Skills</a>, particularly after watching this video from AI Engineer:</p>\n<div class=\"flex place-items-center justify-center items-center rounded-sm mx-auto\"><iframe src=\"https://www.youtube.com/embed/CEvIs9y1uog\" width=\"800\" height=\"400\"></iframe></div>\n<br>\n<p>Simon Willison's blog <a href=\"https://simonwillison.net/2025/Oct/16/claude-skills/\" target=\"_blank\" rel=\"noopener noreferrer\">\"Claude Skills are awesome, maybe a bigger deal than MCP\"</a> is also an amazing read on the subject.</p>\n<p>However, the best way to learn any technology is to get your hands dirty. Attending conferences isn't enough. Reading about it isn't enough. You need to build something, and you're better off when you have a real problem to solve.</p>\n<p>Here was mine: I listen to a lot of podcasts. They're full of incredible nuggets I want to share, but nobody wants a link to a 90-minute episode with \"trust me, minute 47 is awesome.\" I'd tried various clipping tools - paid ones with watermarks, free ones that were painful, even Claude Code with a lot of back-and-forth. Nothing worked in one shot.</p>\n<p>Then I thought about my friend Jordi Visser (ex-CIO of Weiss Multi-Strategy), who produces a <a href=\"https://www.youtube.com/watch?v=dgUnl5agSmw\" target=\"_blank\" rel=\"noopener noreferrer\">weekly macro podcast</a> essentially on his own. There's so much shareable content in his episodes that never gets extracted. I wanted to build something he could use too.</p>\n<p>Skills seemed like the right abstraction. I knew Claude Code <em>could</em> do this after enough iteration, but with Skills, I could package deterministic tools the agent could use off the shelf.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"the-approach-input-to-output-first\">The approach: INPUT to OUTPUT first<a href=\"https://didierlopes.com/blog/i-built-a-claude-skill-that-turns-podcasts-into-shareable-clips#the-approach-input-to-output-first\" class=\"hash-link\" aria-label=\"Direct link to The approach: INPUT to OUTPUT first\" title=\"Direct link to The approach: INPUT to OUTPUT first\">​</a></h2>\n<p>At the start of any project, I bridge INPUT to OUTPUT at a high level. Make sure the connection works, then double down on everything in between.</p>\n<p><strong>Inputs:</strong></p>\n<ul>\n<li>Video URL (<em>required</em>)</li>\n<li>Number of clips, min/max duration, specific focus areas (<em>optional</em>)</li>\n</ul>\n<br>\n<p><strong>Outputs (one folder per clip):</strong></p>\n<ul>\n<li><code>metadata.json</code> — clip title, start/end times, selection rationale</li>\n<li><code>transcript.txt</code> — ready to copy-paste</li>\n<li><code>clip.mp4</code> — ready to share</li>\n</ul>\n<br>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"1-make-it-work\">1. Make it work<a href=\"https://didierlopes.com/blog/i-built-a-claude-skill-that-turns-podcasts-into-shareable-clips#1-make-it-work\" class=\"hash-link\" aria-label=\"Direct link to 1. Make it work\" title=\"Direct link to 1. Make it work\">​</a></h2>\n<p>First goal: make it work in one shot. A single prompt like \"get 3 clips under 2 minutes from this URL\" should produce three folders with all the outputs.</p>\n<p>I gave Claude Code the input/output spec, a rough workflow, the <a href=\"https://docs.anthropic.com/en/docs/claude-code/skills\" target=\"_blank\" rel=\"noopener noreferrer\">Skills documentation</a>, and a <a href=\"https://github.com/michalparkola/tapestry-skills-for-claude-code/blob/main/youtube-transcript/SKILL.md\" target=\"_blank\" rel=\"noopener noreferrer\">reference Skill that uses YouTube</a>.</p>\n<p>It started with a PRD we agreed on, then converted it into a Skill. I gave it a URL. It worked.</p>\n<p>But it was <strong>rough around the edges</strong>.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"2-make-it-good\">2. Make it good<a href=\"https://didierlopes.com/blog/i-built-a-claude-skill-that-turns-podcasts-into-shareable-clips#2-make-it-good\" class=\"hash-link\" aria-label=\"Direct link to 2. Make it good\" title=\"Direct link to 2. Make it good\">​</a></h2>\n<p>\"Good\" depends on perspective. You acquire taste by using many products and noticing what separates good from bad experiences. Since I was my own end user, I could iterate fast.</p>\n<p>I tried different use cases - e.g.:</p>\n<ul>\n<li>Get me 3 clips under 2 minutes</li>\n<li>Grab the clip about the AI bubble and startup valuations</li>\n<li>Get the 1 most controversial take of this podcast</li>\n</ul>\n<br>\n<p>A few things I noticed and fixed:</p>\n<ul>\n<li>The transcript needed polish for easy copy-paste to X</li>\n<li>The transcript missed some text that showed up in the video</li>\n<li>Clips needed subtitles (I often watch without sound)</li>\n<li>Metadata was too sparse - I added the video URL with timestamp and the reasoning behind clip selection (insight, controversy, engagement potential)</li>\n</ul>\n<br>\n<p>I kept iterating until I was happy, then asked Claude to update the Skill based on our final workflow.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"3-make-it-fast\">3. Make it fast<a href=\"https://didierlopes.com/blog/i-built-a-claude-skill-that-turns-podcasts-into-shareable-clips#3-make-it-fast\" class=\"hash-link\" aria-label=\"Direct link to 3. Make it fast\" title=\"Direct link to 3. Make it fast\">​</a></h2>\n<p>Everything worked well now. But it was slow.</p>\n<p>The bottleneck: Claude Code only had the Skill markdown prompt. Every script and command was being created on the fly.</p>\n<p>So I added pre-built Python tools to my Skills folder. Instead of reasoning through script creation every time, the agent could execute tools directly. In one case, it even created a CLI with configurable arguments.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"why-skills-are-a-weird-and-powerful-abstraction\">Why Skills are a weird and powerful abstraction<a href=\"https://didierlopes.com/blog/i-built-a-claude-skill-that-turns-podcasts-into-shareable-clips#why-skills-are-a-weird-and-powerful-abstraction\" class=\"hash-link\" aria-label=\"Direct link to Why Skills are a weird and powerful abstraction\" title=\"Direct link to Why Skills are a weird and powerful abstraction\">​</a></h2>\n<p>Skills aren't just prompts, but they're also not as complex as building a sub-agent.</p>\n<p>I considered writing a Python CLI myself - let an AI model pick start/end times and be done with it. But that only works if I can one-shot my use case. What happens when I want \"shift the window by 20 seconds\" or \"find similar topics across these five videos\"?</p>\n<p>Skills keep the workflow open-ended. The agent can traverse the tooling universe and pick whatever's needed to get the job done.</p>\n<p>This is what made the experience strange: I was watching the agent execute commands, create scripts, and build a more deterministic Python tool for downloading YouTube videos - all things I would have done myself, but it would have taken me a day. The agent was churning them out on the fly.</p>\n<p>And I could iterate alongside it.</p>\n<p>I can see where this is going. You have a conversation with Claude where you figure out a workflow through iteration. Then you say: \"now turn this into a Skill\".</p>\n<p>It's not that different from human memory, when you do something, you learn how to do it.</p>\n<p><strong>Except in this case, I can add skills from other humans/agents to my toolset.</strong></p>\n<p>Incredible times ahead.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"how-to-use-it\">How to use it<a href=\"https://didierlopes.com/blog/i-built-a-claude-skill-that-turns-podcasts-into-shareable-clips#how-to-use-it\" class=\"hash-link\" aria-label=\"Direct link to How to use it\" title=\"Direct link to How to use it\">​</a></h2>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"step-0-set-up-claude-code\">Step 0: Set up Claude Code<a href=\"https://didierlopes.com/blog/i-built-a-claude-skill-that-turns-podcasts-into-shareable-clips#step-0-set-up-claude-code\" class=\"hash-link\" aria-label=\"Direct link to Step 0: Set up Claude Code\" title=\"Direct link to Step 0: Set up Claude Code\">​</a></h3>\n<p><a href=\"https://docs.anthropic.com/en/docs/claude-code/getting-started\" target=\"_blank\" rel=\"noopener noreferrer\">Set up Claude Code</a> - Install, authenticate, and start using Claude Code on your development machine.</p>\n<p>Or make sure you update it with</p>\n<div class=\"language-bash codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-bash codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">npm install -g @anthropic-ai/claude-code</span><br></span></code></pre></div></div>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"step-1-run-cc\">Step 1: Run CC<a href=\"https://didierlopes.com/blog/i-built-a-claude-skill-that-turns-podcasts-into-shareable-clips#step-1-run-cc\" class=\"hash-link\" aria-label=\"Direct link to Step 1: Run CC\" title=\"Direct link to Step 1: Run CC\">​</a></h3>\n<div class=\"language-bash codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-bash codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">claude</span><br></span></code></pre></div></div>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"step-2-install-the-get-y2b-clips-plugin\">Step 2: Install the get-y2b-clips plugin<a href=\"https://didierlopes.com/blog/i-built-a-claude-skill-that-turns-podcasts-into-shareable-clips#step-2-install-the-get-y2b-clips-plugin\" class=\"hash-link\" aria-label=\"Direct link to Step 2: Install the get-y2b-clips plugin\" title=\"Direct link to Step 2: Install the get-y2b-clips plugin\">​</a></h3>\n<p>Run:</p>\n<div class=\"language-bash codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-bash codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">/plugin</span><br></span></code></pre></div></div>\n<p align=\"center\"><img width=\"800\" src=\"https://didierlopes.com/blog/2025-12-22-i-built-a-claude-skill-that-turns-podcasts-into-shareable-clips_1.webp\" alt=\"Plugin command in Claude Code\"></p>\n<p>Click \"Add Marketplace\" and add <strong>DidierRLopes/get-y2b-clips</strong></p>\n<p align=\"center\"><img width=\"800\" src=\"https://didierlopes.com/blog/2025-12-22-i-built-a-claude-skill-that-turns-podcasts-into-shareable-clips_2.webp\" alt=\"Add Marketplace dialog\"></p>\n<p>Then go into Marketplaces tab again and click on it.</p>\n<p align=\"center\"><img width=\"800\" src=\"https://didierlopes.com/blog/2025-12-22-i-built-a-claude-skill-that-turns-podcasts-into-shareable-clips_3.webp\" alt=\"Marketplace tab\"></p>\n<p>Then select one of the \"Install\" options.</p>\n<p align=\"center\"><img width=\"800\" src=\"https://didierlopes.com/blog/2025-12-22-i-built-a-claude-skill-that-turns-podcasts-into-shareable-clips_4.webp\" alt=\"Install options\"></p>\n<p>And finally you will have this skill installed</p>\n<p align=\"center\"><img width=\"800\" src=\"https://didierlopes.com/blog/2025-12-22-i-built-a-claude-skill-that-turns-podcasts-into-shareable-clips_5.webp\" alt=\"Skill installed confirmation\"></p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"step-3-try-it-out\">Step 3: Try it out<a href=\"https://didierlopes.com/blog/i-built-a-claude-skill-that-turns-podcasts-into-shareable-clips#step-3-try-it-out\" class=\"hash-link\" aria-label=\"Direct link to Step 3: Try it out\" title=\"Direct link to Step 3: Try it out\">​</a></h3>\n<blockquote>\n<p>Use get-y2b-clips on <a href=\"https://www.youtube.com/watch?v=Ps8PQOryRSU\" target=\"_blank\" rel=\"noopener noreferrer\">https://www.youtube.com/watch?v=Ps8PQOryRSU</a> to get one clip from Jordi talking about Gavin Baker's interview with Patrick O'Shaughnessy and then another clip that is no more than 1m30s long that is the most controversial take from Jordi in the entire video.</p>\n</blockquote>\n<p style=\"font-size:0.85em\">Prompt I used to trigger my get-y2b-clips skill on CC</p>\n<p align=\"center\"><img width=\"800\" src=\"https://didierlopes.com/blog/2025-12-22-i-built-a-claude-skill-that-turns-podcasts-into-shareable-clips_6.webp\" alt=\"Prompt I used to trigger my get-y2b-clips skill on CC\"></p>\n<p>Here's one of the outputs: <a href=\"https://x.com/didier_lopes/status/2002746090408333635\" target=\"_blank\" rel=\"noopener noreferrer\">https://x.com/didier_lopes/status/2002746090408333635</a></p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"open-source-code\">Open source code<a href=\"https://didierlopes.com/blog/i-built-a-claude-skill-that-turns-podcasts-into-shareable-clips#open-source-code\" class=\"hash-link\" aria-label=\"Direct link to Open source code\" title=\"Direct link to Open source code\">​</a></h2>\n<p><a href=\"https://github.com/DidierRLopes/get-y2b-clips\" target=\"_blank\" rel=\"noopener noreferrer\">GitHub - DidierRLopes/get-y2b-clips</a>: YouTube nuggets extraction via Claude Code Skill</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/i-built-a-claude-skill-that-turns-podcasts-into-shareable-clips",
            "title": "I built a Claude Skill that turns podcasts into shareable clips",
            "summary": "Skills might be the right abstraction for agentic workflows",
            "date_modified": "2025-12-22T00:00:00.000Z",
            "tags": [
                "claude",
                "ai",
                "skills",
                "podcast",
                "automation",
                "open-source"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/the-bitter-lesson-of-context-metadata",
            "content_html": "<p><img decoding=\"async\" loading=\"lazy\" alt=\"The bitter lesson of context metadata\" src=\"https://didierlopes.com/assets/images/2025-12-17-the-bitter-lesson-of-context-metadata-f43339941867307d83886da460bf45fb.webp\" width=\"630\" height=\"630\" class=\"img_ev3q\"></p>\n<p>Stop adding business logic to your datasets.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>The beginners don't think about metadata at all - they just dump raw data and move on. Most obsess over it, adding elaborate contextual metadata to every dataset. The experienced devs come full circle: they use minimal metadata too.</p>\n<p><strong>Less is more, and let me tell you why.</strong></p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-12-17-the-bitter-lesson-of-context-metadata_1.webp\" alt=\"IQ curve showing beginners and experts both using minimal metadata\"></p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"why-more-metadata-limits-your-agent-potential\">Why more metadata limits your agent potential<a href=\"https://didierlopes.com/blog/the-bitter-lesson-of-context-metadata#why-more-metadata-limits-your-agent-potential\" class=\"hash-link\" aria-label=\"Direct link to Why more metadata limits your agent potential\" title=\"Direct link to Why more metadata limits your agent potential\">​</a></h2>\n<p>Walk into most financial firms today and you'll find data teams frantically enriching datasets with contextual metadata. They think they're being helpful.</p>\n<p>A news headlines dataset gets annotated: <em>\"Market-moving financial news optimized for sentiment analysis. Pre-filtered for sentiment-bearing language. Link to ticker symbols for trading signals. Cross-reference with earnings calendar for event-driven analysis.\"</em></p>\n<p>Earnings call transcripts get tagged: <em>\"Management commentary for fundamental analysis. Extract forward guidance and compare to analyst estimates. Score management tone for confidence signals. Primary source for qualitative assessment.\"</em></p>\n<p>This looks sophisticated, but it's actually not a good idea.</p>\n<p>The core mistake: <strong>you're baking business logic into data.</strong></p>\n<p>First, <strong>you're overfitting to known use cases.</strong> That news dataset \"optimized for sentiment analysis\"? You've just made it miss using that data for regulatory monitoring, compliance tracking, thematic research, and portfolio rebalancing workflows. The same data could serve a dozen purposes, but your metadata has steered agent for a specific singular-purpose use case.</p>\n<p>A risk team wants to scan headlines for regulatory announcements. A compliance officer needs disclosure triggers. A thematic analyst is tracking industry narratives. But your metadata keeps screaming \"this is sentiment data for trading\". You're actually constraining the value of this data.</p>\n<p>Second, <strong>your metadata may evolve over time.</strong> Business logic changes. Market structure evolves. New workflows appear. That elaborate context metadata you wrote? It's no longer valid, steering people away from valid uses because the documentation says the data is \"for\" something else.</p>\n<p>Static annotations can't keep up with dynamic needs. Every time you write \"this dataset enables alpha generation through sentiment extraction\", you're limiting the true potential of this dataset.</p>\n<p>Third, and this is the big one, <strong>you're lobotomizing your agents.</strong> You hired intelligent AI systems to reason about data, then you pre-decided how they should think about it. You've stolen the reasoning step and replaced it with instructions.</p>\n<p>It's like hiring a chess grandmaster and handing them a playbook of pre-approved moves. The whole point of having a grandmaster is that they can see combinations you can't.</p>\n<p><strong>But you've constrained them to patterns you already know.</strong></p>\n<p>When you tell an agent \"this news data is for sentiment analysis, join it with market data on tickers, use it to predict price movements\", you've eliminated the agent's ability to discover that the same data could reveal regulatory risk, identify sector rotation, or flag portfolio rebalancing triggers.</p>\n<p><strong>Every line of business context you add is a constraint you're imposing on future intelligence.</strong></p>\n<p>And here's what really matters in finance: <strong>alpha doesn't live in individual datasets</strong>. It emerges at intersections, when you combine datasets in non-obvious ways. A news headline alone tells you something happened. The insight comes when you overlay market data, options flow, portfolio holdings, sector performance, and historical patterns.</p>\n<p>But if you've pre-decided how each dataset should be used, you've pre-decided which intersections are \"valid\". You've turned your data infrastructure into a map with pre-drawn routes, when the whole point of intelligent agents is that they can discover new paths.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"the-sophisticated-answer-do-almost-nothing\">The sophisticated answer: Do almost nothing<a href=\"https://didierlopes.com/blog/the-bitter-lesson-of-context-metadata#the-sophisticated-answer-do-almost-nothing\" class=\"hash-link\" aria-label=\"Direct link to The sophisticated answer: Do almost nothing\" title=\"Direct link to The sophisticated answer: Do almost nothing\">​</a></h2>\n<p>So what should you actually do?</p>\n<p><strong>Keep datasets brutally minimal.</strong></p>\n<p>Structural metadata only:</p>\n<ul>\n<li>Schema (what columns exist)</li>\n<li>Data types (string, integer, timestamp)</li>\n<li>Lineage (where this came from)</li>\n<li>Update frequency (how fresh it is)</li>\n<li>Provenance (who owns it)</li>\n</ul>\n<br>\n<p>That's it. No business definitions. No use case documentation. No \"this data is for X analysis\" guidance. No elaborate context about what the data \"means\" or \"enables\".</p>\n<p>Just clean, structural information that describes the data technically without telling anyone how to think about it.</p>\n<p><strong>Let the data be dumb. Let the agent be smart.</strong></p>\n<p>Here's what this looks like in practice. Take those earnings call transcripts. Instead of pre-annotating them with business logic, you provide minimal metadata: timestamp, company identifier, speaker labels, transcript text. Clean structure, zero interpretation.</p>\n<p>Now an advanced agent needs to build a fundamental analysis model. It doesn't read your instructions. It reasons:</p>\n<p><em>\"I'm validating management guidance. Transcripts contain forward-looking statements that need verification. I'll extract revenue and margin guidance from management remarks, pull analyst consensus from estimation databases, grab actual results from next quarter's financials, and check insider trading activity around the call date. If management's confidence doesn't align with their personal trading behavior, that's a signal. If guidance consistently diverges from results, that's another signal\".</em></p>\n<p>Nobody told it to combine transcripts + estimates + actuals + insider trades. It understood the analytical goal and reasoned about which data combinations would answer it.</p>\n<p>That's the difference. Pre-written metadata tells agents how data <em>has been</em> used. Agent intelligence figures out how it <em>can be</em> used.</p>\n<p>And this is why minimal metadata wins: <strong>maximum flexibility equals maximum value.</strong></p>\n<p>The same earnings transcript can serve fundamental analysis, sentiment modeling, thematic research, competitive intelligence, and risk assessment. All without conflicting metadata pulling in different directions. Each workflow gets what it needs because the agent reasons about combinations dynamically, not because someone documented every possible use case upfront.</p>\n<p>Context isn't pre-written in documentation. It's computed at runtime based on goals.</p>\n<p>Agents adapt to novel situations, discover unexpected data combinations, and avoid the maintenance burden of outdated annotations. Most importantly: they find alpha at intersections you didn't anticipate, because you haven't told them which intersections are \"allowed\".</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"less-is-more\">Less is more<a href=\"https://didierlopes.com/blog/the-bitter-lesson-of-context-metadata#less-is-more\" class=\"hash-link\" aria-label=\"Direct link to Less is more\" title=\"Direct link to Less is more\">​</a></h2>\n<p>If you're enriching datasets with elaborate contextual metadata, stop. You're building at the wrong layer.</p>\n<p><strong>The practical shift:</strong></p>\n<p><strong>Stop:</strong> Adding business logic to datasets. Documenting use cases in metadata. Pre-deciding how data should be combined. Trying to make datasets \"self-explanatory\" with context.</p>\n<p><strong>Start:</strong> Keeping datasets structurally clean. Building agent intelligence that reasons about combinations. Trusting AI to figure out context based on goals.</p>\n<p>At OpenBB, we've designed around this philosophy. Users select which widget metadata gets exposed to agents - they control what context is available rather than inheriting someone else's assumptions. More importantly, users build their own agents and integrate them into their workspace, defining context based on what actually matters for their specific workflows. The agents aren't reading generic dataset descriptions. They're reasoning within user-defined contexts about which data to combine and why.</p>\n<p>This is the shift: from data teams trying to predict every use case, to agents defining context dynamically based on actual work.</p>\n<p><strong>Both extremes of the IQ curve arrive at minimal metadata. One by accident, they never thought about it. One by design, they understand that intelligence lives in agents, not annotations.</strong></p>\n<p>The difference between them? Knowing that context is a property of use, not data. That flexibility beats comprehensiveness. That the smartest datasets are the most generic.</p>\n<p><strong>The smartest thing you can do with your data is almost nothing.</strong></p>\n<p>Stop over-engineering.</p>\n<p>Start trusting your AI.</p>\n<p>Less is more.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/the-bitter-lesson-of-context-metadata",
            "title": "The bitter lesson of context metadata",
            "summary": "Stop adding business logic to your datasets",
            "date_modified": "2025-12-17T00:00:00.000Z",
            "tags": [
                "ai",
                "data",
                "metadata",
                "agents",
                "openbb",
                "finance"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/your-ai-team-isnt-doing-ai-theyre-rebuilding-infrastructure",
            "content_html": "<p><img decoding=\"async\" loading=\"lazy\" alt=\"Your AI team isn&amp;#39;t doing AI. They&amp;#39;re rebuilding infrastructure.\" src=\"https://didierlopes.com/assets/images/2025-12-09-your-ai-team-isnt-doing-ai-theyre-rebuilding-infrastructure-72638f30caa039f871be070674a7eb48.webp\" width=\"945\" height=\"630\" class=\"img_ev3q\"></p>\n<p>From weekend POC to production: the 24-month gap nobody talks about.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>You know the story. Someone on your team builds a Streamlit chatbot over a weekend. They feed it your research documents, hook it up to OpenAI, and boom – it works.</p>\n<p>It actually works. You demo it to leadership. Everyone gets excited.</p>\n<p><em>\"This is it. This is our AI system.\"</em></p>\n<p><strong>Except that it isn't.</strong></p>\n<p>Six months later, you realize that the weekend POC is nothing like what you actually need. Context management doesn't work at scale. The AI hallucinates in production. It can't handle complex workflows. Data security is a nightmare. You don't have audit trails. And your best engineers? They're still in the weeds, wiring APIs, debugging context windows, building data pipelines, handling compliance requirements. They're not doing AI innovation. They're stuck doing foundational infrastructure work that every other firm is also doing.</p>\n<p>And guess what?</p>\n<p>Our OpenBB Copilot started exactly like that. But that was more than 2 years ago.</p>\n<p>Don't believe me? Look at this demo in December 2023, where we already had an AI chatbot integrated with the workspace that was able to handle structured and unstructured data.</p>\n<div class=\"flex place-items-center justify-center items-center rounded-sm mx-auto\"><iframe src=\"https://www.youtube.com/embed/V1rYmWWVbIY\" width=\"800\" height=\"400\"></iframe></div>\n<br>\n<p>The difference?</p>\n<p>We didn't stop there. We spent the next years, and a couple of $M in R&amp;D, learning what it actually takes to go from \"fun experiment\" to \"production system that financial teams can trust\".</p>\n<p>We learned the hard way what a CTO actually needs when you're operating at scale: sophisticated context management, proper data governance, audit trails, security that doesn't compromise workflow, AI that's genuinely agentic and not just chatty.</p>\n<p align=\"center\"><img width=\"800\" src=\"https://didierlopes.com/blog/2025-12-09-your-ai-team-isnt-doing-ai-theyre-rebuilding-infrastructure_1.webp\" alt=\"7 level context layers slide from training workshop\"></p>\n<p align=\"center\" style=\"font-size:0.85em;margin-top:-0.5em\">Slide from our training workshop deck that shows the 7 level of context layers that the agent has to navigate, with each of these layers having sometimes hundreds to thousands of datasets.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"the-foundation-problem\">The foundation problem<a href=\"https://didierlopes.com/blog/your-ai-team-isnt-doing-ai-theyre-rebuilding-infrastructure#the-foundation-problem\" class=\"hash-link\" aria-label=\"Direct link to The foundation problem\" title=\"Direct link to The foundation problem\">​</a></h2>\n<p>Most teams approach AI the same way: start from zero, wire together APIs, paste some prompt engineering on top, and hope it scales. This works until it doesn't. You're managing context windows, debugging agent hallucinations, building retrieval pipelines, handling data governance, integrating with proprietary systems - essentially rebuilding the same foundational plumbing that hundreds of other firms are also rebuilding in parallel.</p>\n<p>It's a massive waste of engineering effort.</p>\n<p>Getting from \"ChatGPT chatbot\" to \"production AI system that actually works\" takes 24+ months of serious engineering work. Most teams don't have that. More importantly, your best quants and engineers get pulled away from high-value work, actual research, trading strategy, portfolio analysis, to build foundational infrastructure.</p>\n<p>That's not an investment; it's opportunity cost.</p>\n<p>Every month your top engineers spend on plumbing is a month they're not generating alpha or building your competitive advantage.</p>\n<p>I think there's a better way.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"what-were-offering-enterprise-clients\">What we're offering enterprise clients<a href=\"https://didierlopes.com/blog/your-ai-team-isnt-doing-ai-theyre-rebuilding-infrastructure#what-were-offering-enterprise-clients\" class=\"hash-link\" aria-label=\"Direct link to What we're offering enterprise clients\" title=\"Direct link to What we're offering enterprise clients\">​</a></h2>\n<p>For our largest enterprise clients (above a certain seat count or contract size), we're providing source-available access to OpenBB Copilot. This is our AI system - the one we've spent over two years and a couple of $M in R&amp;D building.</p>\n<p>You get the code. You get the architecture. You get two years of hard-earned lessons about what actually works in production.</p>\n<p>Here's what that means in practice:</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"1-you-skip-the-24-month-foundational-build\">1. You skip the 24-month foundational build<a href=\"https://didierlopes.com/blog/your-ai-team-isnt-doing-ai-theyre-rebuilding-infrastructure#1-you-skip-the-24-month-foundational-build\" class=\"hash-link\" aria-label=\"Direct link to 1. You skip the 24-month foundational build\" title=\"Direct link to 1. You skip the 24-month foundational build\">​</a></h3>\n<p>Instead of your team spending the next two years reinventing context management, agentic patterns (e.g. RAG), output validation, reasoning, citations, structured with unstructured data, URLs, MCPs, and data governance, they get a proven system from day one.</p>\n<p>They can inspect the code, understand the design decisions, and extend it for your specific use cases. That's 24 months of engineering time you just reclaimed.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"2-you-get-a-system-built-for-real-world-investment-workflows\">2. You get a system built for real-world investment workflows<a href=\"https://didierlopes.com/blog/your-ai-team-isnt-doing-ai-theyre-rebuilding-infrastructure#2-you-get-a-system-built-for-real-world-investment-workflows\" class=\"hash-link\" aria-label=\"Direct link to 2. You get a system built for real-world investment workflows\" title=\"Direct link to 2. You get a system built for real-world investment workflows\">​</a></h3>\n<p>Copilot wasn't designed in a lab - it was built to handle actual problems: connecting to multiple data sources, maintaining context across complex reasoning chains, enforcing data entitlements, handling compliance requirements, producing outputs that fit into real decision-making.</p>\n<p>The architecture treats AI as a first-class component of a workflow, not a chatbot afterthought. Features like sophisticated context management (understanding which data sources matter most), dynamic widget parameter modification (automatically adjusting queries based on your needs), step-by-step reasoning visibility (so you can audit how the AI arrived at answers) and citations (even at the document sentence level) make the difference between a toy and a tool you can actually trust.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"3-you-can-customize-and-own-it\">3. You can customize and own it<a href=\"https://didierlopes.com/blog/your-ai-team-isnt-doing-ai-theyre-rebuilding-infrastructure#3-you-can-customize-and-own-it\" class=\"hash-link\" aria-label=\"Direct link to 3. You can customize and own it\" title=\"Direct link to 3. You can customize and own it\">​</a></h3>\n<p>Because you have source access, you're not locked into our roadmap or dependent on our support schedule. Your team can extend it, integrate it with proprietary systems, swap out models, add your own data sources – whatever your strategy requires.</p>\n<p>You build your secret sauce on top of a solid foundation instead of building the foundation itself.</p>\n<p>Damn, you can even rebrand it internally to \"Not OpenBB agent\".</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"4-youre-not-starting-from-zero-on-security-and-governance\">4. You're not starting from zero on security and governance<a href=\"https://didierlopes.com/blog/your-ai-team-isnt-doing-ai-theyre-rebuilding-infrastructure#4-youre-not-starting-from-zero-on-security-and-governance\" class=\"hash-link\" aria-label=\"Direct link to 4. You're not starting from zero on security and governance\" title=\"Direct link to 4. You're not starting from zero on security and governance\">​</a></h3>\n<p>Enterprise AI is risky. Data leaks, compliance violations, audit trails - this stuff matters. Copilot was built with the workspace enterprise requirements from day one: on-prem deployment options, SSO, role-based access control, SOC2 compliance, proper data entitlement enforcement. Your team isn't reinventing the security wheel; they're extending a system that was built to be secure.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"5-out-of-the-box-financial-environment-designed-for-it-to-thrive\">5. Out-of-the-box financial environment designed for it to thrive<a href=\"https://didierlopes.com/blog/your-ai-team-isnt-doing-ai-theyre-rebuilding-infrastructure#5-out-of-the-box-financial-environment-designed-for-it-to-thrive\" class=\"hash-link\" aria-label=\"Direct link to 5. Out-of-the-box financial environment designed for it to thrive\" title=\"Direct link to 5. Out-of-the-box financial environment designed for it to thrive\">​</a></h3>\n<p>Here's what most AI companies miss: a copilot is only as good as the environment it operates in. Copilot doesn't sit in isolation. It lives inside OpenBB Workspace, a purpose-built financial analysis platform with sophisticated context management, dynamic widget systems, parameter linking across dashboards, and native integration with your proprietary data sources.</p>\n<p>This means Copilot understands the structure of your analysis – which data matters, which widgets are active, what parameters your team is using.</p>\n<p>It's not just a chatbot bolted onto a generic system. It's an AI agent that's designed to orchestrate across your entire analytical environment. Your team gets access to the full capability stack: visualization, data integration, workflow automation, and AI reasoning - all built to work together.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"why-this-is-the-best-bootstrap-available\">Why this is the best bootstrap available<a href=\"https://didierlopes.com/blog/your-ai-team-isnt-doing-ai-theyre-rebuilding-infrastructure#why-this-is-the-best-bootstrap-available\" class=\"hash-link\" aria-label=\"Direct link to Why this is the best bootstrap available\" title=\"Direct link to Why this is the best bootstrap available\">​</a></h2>\n<p>The core insight is simple: you can't innovate on the foundation while you're building it. Your best engineers get stuck doing plumbing. Your timeline stretches. Your cost balloons. And by the time you finish, the market has moved on.</p>\n<p>With source-available access to Copilot, your team can start from a foundation that's already been battle-tested by real investors and quants using it in production. They can focus on what makes your firm different: your data, your workflows, your intellectual property - instead of rebuilding what every other firm is also rebuilding.</p>\n<p>But there's another advantage: OpenBB continues investing heavily in the foundational layer of Copilot (and workspace).</p>\n<p>We're pouring capital into making it better, faster, and smarter - exactly as we have for over two years.</p>\n<p>That ongoing investment benefits you directly. Your team gets access to improvements, new capabilities, and deeper financial domain understanding without having to fund the R&amp;D themselves.</p>\n<p>And because we're working across multiple firms and use cases, we're continuously learning what financial teams actually need to get done - which means the platform evolves with the industry, not in isolation. <strong>For instance, we were the first workspace to support MCP server integration.</strong></p>\n<p>This is how AI actually succeeds at investment firms: not by buying a generic tool, not by building from scratch, but by starting with proven infrastructure and layering their own innovation on top.</p>\n<p>The firms that move fastest aren't the ones with the biggest budgets for AI, <strong>they're the ones that don't waste their budgets on foundational problems that have already been solved.</strong></p>\n<p>Source-available Copilot is that solve.</p>\n<p>Your team gets over two years of R&amp;D and a production-grade system. They focus on making it uniquely valuable for your investment process.</p>\n<p>Everyone wins.</p>\n<p>The question isn't whether your firm will use AI - it's whether you'll spend the next 24 months building what already exists, or the next 24 months actually innovating with it.</p>\n<p>PS: Last week I shared an open source agent that I built over a weekend, our copilot is that + years of hard work. But if you want to get a glimpse to what you would get, I recommend starting from here: <a href=\"https://didierlopes.com/blog/introducing-osor-agent\" target=\"_blank\" rel=\"noopener noreferrer\">Introducing OSOR Agent</a></p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/your-ai-team-isnt-doing-ai-theyre-rebuilding-infrastructure",
            "title": "Your AI team isn't doing AI. They're rebuilding infrastructure.",
            "summary": "From weekend POC to production - the 24-month gap nobody talks about",
            "date_modified": "2025-12-09T00:00:00.000Z",
            "tags": [
                "ai",
                "infrastructure",
                "enterprise",
                "openbb",
                "startup",
                "finance"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/introducing-osor-agent",
            "content_html": "<p><img decoding=\"async\" loading=\"lazy\" alt=\"Introducing OSOR Agent\" src=\"https://didierlopes.com/assets/images/2025-12-02-introducing-osor-agent-b822cbd3563f8166be0d45572d2315d3.webp\" width=\"1200\" height=\"587\" class=\"img_ev3q\"></p>\n<p>How I quickly hot-swap my financial agent with different LLM providers - fully open source.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>When Gemini 3.0 dropped last week, I wanted to test it immediately.</p>\n<p>But I have to go to Google AI Studio, and none of my data is there...</p>\n<p>And I couldn't be bothered to drop CSV files or asking Claude Code to use it via API simply.</p>\n<p>However, I have OpenBB workspace - which:</p>\n<ul>\n<li>Has the financial data I care about</li>\n<li>AND I can bring my own agent</li>\n</ul>\n<br>\n<p>Silly me...</p>\n<p>So, I spent Saturday building <strong>OSOR Agent</strong> - a bridge between two problems:</p>\n<ol>\n<li>New models drop constantly, but testing them with financial data requires jumping between platforms</li>\n<li>OpenBB has all the financial data infrastructure, but no easy way to experiment with different LLM backends</li>\n</ol>\n<br>\n<p>So I built something that solves both.</p>\n<p>Before we start, here's the entire agent code fully open source: <a href=\"https://github.com/DidierRLopes/openbb-open-router-agent\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/DidierRLopes/openbb-open-router-agent</a></p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"what-osor-agent-does\">What OSOR Agent Does<a href=\"https://didierlopes.com/blog/introducing-osor-agent#what-osor-agent-does\" class=\"hash-link\" aria-label=\"Direct link to What OSOR Agent Does\" title=\"Direct link to What OSOR Agent Does\">​</a></h2>\n<p>OSOR Agent combines OpenBB's data &amp; infra layer with Open Router's model flexibility.</p>\n<p>Here's what that actually means:</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"pick-any-model-anytime\">Pick Any Model, Anytime<a href=\"https://didierlopes.com/blog/introducing-osor-agent#pick-any-model-anytime\" class=\"hash-link\" aria-label=\"Direct link to Pick Any Model, Anytime\" title=\"Direct link to Pick Any Model, Anytime\">​</a></h3>\n<p>Open Router gives you access to hundreds of models - Claude, GPT-4o, Gemini, Grok, open-source models.</p>\n<p>Some are literally free, like Grok 4.1 Fast (as of Nov' 23).</p>\n<p align=\"center\"><img width=\"800\" src=\"https://didierlopes.com/blog/2025-12-02-introducing-osor-agent_1.webp\" alt=\"Open Router model selection showing free models\"></p>\n<p>When a new model drops, you just select it. No new account, no new interface.</p>\n<p align=\"center\"><img width=\"800\" src=\"https://didierlopes.com/blog/2025-12-02-introducing-osor-agent_2.webp\" alt=\"Model selection dropdown in OSOR Agent\"></p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"mature-ai-chatting-interface\">Mature AI Chatting Interface<a href=\"https://didierlopes.com/blog/introducing-osor-agent#mature-ai-chatting-interface\" class=\"hash-link\" aria-label=\"Direct link to Mature AI Chatting Interface\" title=\"Direct link to Mature AI Chatting Interface\">​</a></h3>\n<p>Instead of copy-pasting financial data around, the agent pulls directly from OpenBB widgets. Your market data, portfolio metrics, news, whatever you've connected to your workspace, feeds directly into the LLM context.</p>\n<p>You can also expand AI chat so the remainder of the dashboard disappears.</p>\n<p>It even has access to data via MCP as you can see below, and shares its internal step by step reasoning!</p>\n<p align=\"center\"><img width=\"800\" src=\"https://didierlopes.com/blog/2025-12-02-introducing-osor-agent_3.webp\" alt=\"OSOR Agent showing step by step reasoning with MCP data\"></p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"your-agentic-financial-workspace\">Your Agentic Financial Workspace<a href=\"https://didierlopes.com/blog/introducing-osor-agent#your-agentic-financial-workspace\" class=\"hash-link\" aria-label=\"Direct link to Your Agentic Financial Workspace\" title=\"Direct link to Your Agentic Financial Workspace\">​</a></h3>\n<p>The agent can generate charts, tables, and citations so you're not just reading wall-of-text responses. It understands your data structure and responds accordingly.</p>\n<p align=\"center\"><img width=\"800\" src=\"https://didierlopes.com/blog/2025-12-02-introducing-osor-agent_4.webp\" alt=\"OSOR Agent generating charts and tables\"></p>\n<p>In my opinion, you shouldn't have to choose between testing the latest AI model and having access to your financial data.</p>\n<p>You shouldn't have to manually move data around.</p>\n<p>You shouldn't have to become an expert in multiple platforms.</p>\n<p>OSOR Agent is small, but the principle is big. It treats data access like infrastructure - get it right once, then let people experiment freely on top of it.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"open-source\">Open Source<a href=\"https://didierlopes.com/blog/introducing-osor-agent#open-source\" class=\"hash-link\" aria-label=\"Direct link to Open Source\" title=\"Direct link to Open Source\">​</a></h2>\n<p>The full code is MIT licensed and open source.</p>\n<p>That means you can fork it, extend it, build whatever you want on top of it. Want to add RAG underneath? Build it. Want custom analysis for a specific strategy? Build it.</p>\n<p>The best models are worthless without access to data that matters.</p>\n<p>OSOR Agent is a step in that direction on top of a mature financial workspace, OpenBB Workspace.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"this-is-a-starting-point\">This is a Starting Point<a href=\"https://didierlopes.com/blog/introducing-osor-agent#this-is-a-starting-point\" class=\"hash-link\" aria-label=\"Direct link to This is a Starting Point\" title=\"Direct link to This is a Starting Point\">​</a></h3>\n<p>There's a lot that can be done to improve the agent, this was a weekend project built on top of our vanilla agent examples <a href=\"https://github.com/OpenBB-finance/agents-for-openbb\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/OpenBB-finance/agents-for-openbb</a></p>\n<p>Here's an example of the agent powered by Gemini 3 working with Top Events from Polymarket when asked about what events I should look at within the \"FED\" category.</p>\n<p align=\"center\"><img width=\"800\" src=\"https://didierlopes.com/blog/2025-12-02-introducing-osor-agent_5.webp\" alt=\"OSOR Agent with Polymarket FED events analysis\"></p>\n<p align=\"center\"><img width=\"800\" src=\"https://didierlopes.com/blog/2025-12-02-introducing-osor-agent_6.webp\" alt=\"OSOR Agent detailed analysis of FED events\"></p>\n<p>Contributions are welcome, happy hacking! :)</p>\n<p><a href=\"https://github.com/DidierRLopes/openbb-open-router-agent\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/DidierRLopes/openbb-open-router-agent</a></p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/introducing-osor-agent",
            "title": "Introducing OSOR Agent",
            "summary": "How I quickly hot-swap my financial agent with different LLM providers - fully open source",
            "date_modified": "2025-12-02T00:00:00.000Z",
            "tags": [
                "ai",
                "open-source",
                "openbb",
                "finance",
                "agents",
                "llm"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/the-rise-of-forward-deployed-engineering-in-finance",
            "content_html": "<p>A few weeks ago, we were at the HQ of one of our largest clients (close to 70bn AUM) for a week and although I had this post in draft for a couple of months, these words resonate even more with me now as we experienced this FDE work first-hand.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"Team at client HQ\" src=\"https://didierlopes.com/assets/images/2025-11-25-the-rise-of-forward-deployed-engineering-in-finance_1-7ba405bd96be0f2fcde8e2f4d5c9646b.webp\" width=\"1920\" height=\"1276\" class=\"img_ev3q\"></p>\n<p>Anyway, let's talk about FDE.</p>\n<p>Let me start by sharing an excerpt by Palantir's CTO on the origin of the name \"<em>Forward Deployed Engineer</em>\" and how it relates to how French restaurants works.</p>\n<blockquote>\n<p>In 2006, Alex Karp asked me if I knew why French restaurants were so good. I had no idea. He told me that at a French restaurant, the wait staff is actually part of the kitchen staff. They intimately understand the food, the methodology, and the technique. They are not merely carrying the food from the kitchen to the table, but are instead part of a subtle and complex system that affects kitchen operations. He wanted me to build that, but for engineering.</p>\n<br>\n<p>I did just that, and in 2007, I gave it the name \"forward deployed engineering\" (FDE) in homage to our customers. FDEs embed alongside our customers and work to ensure our software solves their problem and not some proxy for their problem. They're crazy enough to get on a last-minute plane to Iraq, they're smart enough to ship quality, same-day code, and their EQ is still high enough to talk to users (and maybe even enjoy it). Investors ridiculed us for creating a \"services\" role that would only serve to depress the margins of a software company. We didn't look like the other SaaS businesses, something they eventually realized was a feature, not a bug. Just like French restaurants don't blindly hand off food from an uninformed waiter to the diner, we didn't believe in throwing our software over the wall in the hopes the customer would divine the correct meaning from it. This approach built an engineering organization with unmatched creativity, responsiveness, and focus on the primacy of winning.</p>\n</blockquote>\n<br>\n<p><strong>Shyam Sankar (Palantir's CTO)</strong> - <a href=\"https://www.piratewires.com/p/primacy-of-winning-shyam-sankar-palantir\" target=\"_blank\" rel=\"noopener noreferrer\">\"The Primacy of Winning\"</a></p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"the-quiet-truth\">The quiet truth<a href=\"https://didierlopes.com/blog/the-rise-of-forward-deployed-engineering-in-finance#the-quiet-truth\" class=\"hash-link\" aria-label=\"Direct link to The quiet truth\" title=\"Direct link to The quiet truth\">​</a></h2>\n<p>AI-native platforms promise to \"automate financial workflows\". But enterprise wins aren't self-serve trials, they're proof-of-concepts plus forward-deployed engineers.</p>\n<p>Engineers sitting inside client offices. Writing code on their networks. Building bespoke workflows that prove the platform works.</p>\n<p>For every \"AI assistant for analysts\", there are FDEs buried in a buy-side firm's infrastructure, understanding data pipelines, writing agentic workflows, fixing edge cases, etc… The companies landing the biggest customers aren't winning on product alone, they're winning on proximity.</p>\n<p>In finance, no abstraction replaces trust. This isn't a workaround. It's how intelligence software gets deployed in high-stakes domains.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"why-forward-deployment-works\">Why forward deployment works<a href=\"https://didierlopes.com/blog/the-rise-of-forward-deployed-engineering-in-finance#why-forward-deployment-works\" class=\"hash-link\" aria-label=\"Direct link to Why forward deployment works\" title=\"Direct link to Why forward deployment works\">​</a></h2>\n<p>AI-native software isn't plug-and-play. Output quality depends on data specificity and governance. Every firm's architecture is different. Forward deployment brings engineering to the data.</p>\n<p>An embedded engineer does three things pure software can't:</p>\n<ol>\n<li>\n<p><strong>Translates domain into system.</strong> They learn how the firm defines \"exposure\" or \"active position\" and encode those meanings into their workflows.</p>\n</li>\n<li>\n<p><strong>Builds trust loops.</strong> Same Slack channels, real workflows, outputs validated against the firm's sources of truth.</p>\n</li>\n<li>\n<p><strong>Turns deployments into reusable abstractions.</strong> Each new workflow becomes productized logic that can be leveraged for the next client.</p>\n</li>\n</ol>\n<br>\n<p>Most AI companies say they're selling intelligence. They're selling trust. Clients ask what peers are doing. They want the playbook, not just the platform. An engineer inside the firm, fixing pipelines and aligning definitions, builds credibility no deck can.</p>\n<p>Trust compounds. Every successful deployment becomes a reference pattern the engineer can leverage for next client, obviously without sharing the actual workflow.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"the-palantir-playbook\">The Palantir playbook<a href=\"https://didierlopes.com/blog/the-rise-of-forward-deployed-engineering-in-finance#the-palantir-playbook\" class=\"hash-link\" aria-label=\"Direct link to The Palantir playbook\" title=\"Direct link to The Palantir playbook\">​</a></h2>\n<p>The breakthrough wasn't \"work closely with clients\". It was turning embedded work into product leverage.</p>\n<p>Each deployment as live R&amp;D. Engineers discovered reusable patterns: data models, workflows, connectors, ontologies. Those patterns moved into the platform, so the next deployment started smarter.</p>\n<p>The self-scaling loop:</p>\n<ul>\n<li>Engineers deploy → deployment creates insight → insight becomes reusable → product gets stronger → next deployment accelerates</li>\n</ul>\n<br>\n<p>What looked like high-touch work was the most scalable form of enterprise learning. Agentic finance is doing this now. Teams embedding engineers aren't slowing product - they're accelerating it.</p>\n<p>This is the playbook for the agentic era: scale product by deploying where it's most complex. Learn fast, abstract faster.</p>\n<blockquote>\n<p>(…) Specifically, the firm [PLTR] provides a modern AI data platform (i.e., analytical tools, data infrastructure software, AI tooling) that helps government agencies and enterprises make data-driven decisions by detecting unusual or previously undetectable patterns in large complex datasets. Its AI data platform is differentiated by its Ontology, which presents data to users in their own everyday terms and represents decisions in an enterprise, thus becoming a powerful tool for AI-driven decision-making. On top of this, Palantir deploys an effective and super-efficient go-to-market approach that attracts customers and quickly converts them into paying customers of its complex products. (…)</p>\n</blockquote>\n<br>\n<p><strong>Loop Capital's report on February 19th, 2025:</strong> \"Game-Changing Software Play Leading the Enterprise AI Revolution; Initiate Buy\"</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"the-hybrid-flywheel\">The hybrid flywheel<a href=\"https://didierlopes.com/blog/the-rise-of-forward-deployed-engineering-in-finance#the-hybrid-flywheel\" class=\"hash-link\" aria-label=\"Direct link to The hybrid flywheel\" title=\"Direct link to The hybrid flywheel\">​</a></h2>\n<p>PLG dominated the last decade because products were simple and users empowered to self-serve. AI-native finance breaks that logic, it's probabilistic, data-hungry, unpredictable in the wild.</p>\n<p>PLG still matters as half the story. Bottom-up motion builds credibility and reach. But PLG alone doesn't close institutional deals or integrate with legacy systems. In finance, analysts often lack the time or mandate to tinker.</p>\n<p>Forward deployment closes those gaps, but can't scale in isolation. Without strong product underneath, every engagement risks becoming bespoke.</p>\n<p>The future isn't product-led or sales-led. It's deployment-led growth, powered by a product that learns faster with every field engagement.</p>\n<p>Here's the loop:</p>\n<ul>\n<li>\n<p><strong>Open distribution</strong> → rapid experimentation. Free tiers, open examples, extensible interfaces.</p>\n</li>\n<li>\n<p><strong>FDEs</strong> → institutional activation. Embedded engineers integrate, secure, productionize.</p>\n</li>\n<li>\n<p><strong>Field learning</strong> → product leverage. With every integration there are new teachings, that are folded back so the next deployment is faster.</p>\n</li>\n<li>\n<p><strong>Faster deployments</strong> → broader adoption. As the product gets smarter, less custom work is needed. The loop accelerates.</p>\n</li>\n</ul>\n<br>\n<p><strong>Community fuels product. Product fuels deployment. Deployment fuels product again.</strong></p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"one-motion\">One motion<a href=\"https://didierlopes.com/blog/the-rise-of-forward-deployed-engineering-in-finance#one-motion\" class=\"hash-link\" aria-label=\"Direct link to One motion\" title=\"Direct link to One motion\">​</a></h2>\n<p>Bottom-up and top-down are converging.</p>\n<p>The open community and the forward-deployed engineer are two sides of one motion - one learns from scale, the other from proximity. Both feed the same outcome: a smarter, faster, more resilient product.</p>\n<p>The field becomes part of R&amp;D. Every deployed engineer is a node in the product feedback network. Every community user at the edge generates signal for where to go next.</p>\n<p>The AI platforms that win won't just have the best model or most data, they'll have mastered this hybrid motion of openness and proximity.</p>\n<p><strong>The companies that merge field intimacy with open distribution will own the next era of financial software.</strong></p>\n<p>Proximity drives trust. Openness drives scale.</p>\n<p>This is a great video from YC on FDEs:</p>\n<div class=\"flex place-items-center justify-center items-center rounded-sm mx-auto\"><iframe src=\"https://www.youtube.com/embed/Zyw-YA0k3xo\" width=\"800\" height=\"400\"></iframe></div><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/the-rise-of-forward-deployed-engineering-in-finance",
            "title": "The rise of forward-deployed engineering in finance",
            "summary": "AI-native platforms promise to automate financial workflows, but enterprise wins aren't self-serve trials - they're proof-of-concepts plus forward-deployed engineers.",
            "date_modified": "2025-11-25T00:00:00.000Z",
            "tags": [
                "engineering",
                "finance",
                "ai",
                "enterprise",
                "palantir"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/why-generative-ai-isnt-uncovering-alpha-yet",
            "content_html": "<p>In the world of hedge funds, everyone's talking about AI. But recently, Ken Griffin, one of the industry's most respected voices, made a bold claim: generative AI isn't delivering alpha for hedge funds. Instead, it's mainly boosting workflows and productivity.</p>\n<p>He's not entirely wrong but he's not telling the whole story either.</p>\n<p>Here's the thing: the problem isn't that AI lacks the capability to find alpha. The problem is that most firms aren't giving AI the environment it needs to succeed.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"breaking-down-griffins-argument\">Breaking down Griffin's argument<a href=\"https://didierlopes.com/blog/why-generative-ai-isnt-uncovering-alpha-yet#breaking-down-griffins-argument\" class=\"hash-link\" aria-label=\"Direct link to Breaking down Griffin's argument\" title=\"Direct link to Breaking down Griffin's argument\">​</a></h2>\n<p>Let's start by acknowledging Griffin's point. He's correct that a lot of current AI use cases are indeed improving workflows rather than generating new market-beating insights.</p>\n<p>Many firms use AI to automate research summaries, streamline reporting, or speed up documentation reviews. These are valuable applications, no question. But they're fundamentally different from uncovering alpha.</p>\n<p>Griffin's observation reflects a real pattern in how firms are deploying generative AI today. They're thinking about AI first, then providing it with just enough data to complete a specific workflow. It's a narrow, task-focused approach.</p>\n<p>And within those constraints, AI is delivering exactly what you'd expect: <strong>incremental productivity gains</strong>.</p>\n<p>So Griffin isn't wrong. He's just incomplete.</p>\n<p>The real root cause is…</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"lack-of-integrated-workspaces\">Lack of integrated workspaces<a href=\"https://didierlopes.com/blog/why-generative-ai-isnt-uncovering-alpha-yet#lack-of-integrated-workspaces\" class=\"hash-link\" aria-label=\"Direct link to Lack of integrated workspaces\" title=\"Direct link to Lack of integrated workspaces\">​</a></h2>\n<p>Here's where the narrative shifts: the reason AI isn't finding alpha isn't because AI can't find alpha.</p>\n<p><strong>It's because most firms aren't leaning in enough to give AI and the user what they actually need, a unified, collaborative workspace where all their data is fully accessible and integrated.</strong></p>\n<p>Think about where alpha traditionally comes from in hedge funds.</p>\n<p>It emerges at the intersection of insights that no one else has connected yet. It lives in the correlations between datasets that were previously siloed. A trader might notice a pattern across private equity, public equities, and macro data that nobody has synthesized before. That's where edges come from.</p>\n<p>That discovery process isn't meant to be a machine doing it alone in a black box. It's meant to be a conversation. An AI system that can surface patterns and ask \"what if we looked at these datasets together?\" while a human brings domain expertise, intuition, and judgment to interpret what those patterns actually mean for the investment thesis.</p>\n<p>Most firms today don't have that dynamic. They have fragmented data silos, which means the human and AI can't collaborate effectively. The data lives in separate platforms, the insights stay isolated, and neither the AI nor the human can see the full picture.</p>\n<p>It's not a collaboration at all, it's a constraint.</p>\n<p>Now imagine if you could give an AI system access to all of that data simultaneously, in one integrated environment. Not just for the AI to analyze in isolation, but as a true workspace where the AI and human can work together.</p>\n<p>The AI could surface patterns across asset classes, teams, and time periods that humans might miss. It could ask questions like \"have we ever seen these two metrics move together?\" or \"what happens when these conditions align?\" And then a skilled analyst or trader could jump in with context, ask follow-up questions, and develop those insights into real alpha.</p>\n<p><strong>That's the collaboration model that actually works.</strong></p>\n<p>It's not about replacing humans with AI. It's about giving both the human and the AI the environment they need to think together.</p>\n<p><em>I did a small POC at the start of the year of where we are heading, and it's so clear to me that this is the future - watch this 50 second clip.</em></p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"how-a-unified-approach-unlocks-alpha-at-the-intersection\">How a unified approach unlocks alpha at the intersection<a href=\"https://didierlopes.com/blog/why-generative-ai-isnt-uncovering-alpha-yet#how-a-unified-approach-unlocks-alpha-at-the-intersection\" class=\"hash-link\" aria-label=\"Direct link to How a unified approach unlocks alpha at the intersection\" title=\"Direct link to How a unified approach unlocks alpha at the intersection\">​</a></h2>\n<p>When all of a firm's data lives in one place, truly integrated and accessible, something powerful happens.</p>\n<p>The AI and human can actually work together to surface patterns that would never emerge from siloed environments.</p>\n<p>Consider a concrete example: a firm brings together public market data, private market data, macroeconomic indicators, and alternative data sources all in one workspace. An analyst poses a question: \"What correlations emerge when we combine private equity valuations with macro conditions and public market movements?\" The AI agent analyzes this unified dataset and surfaces patterns. Maybe it discovers that certain private equity valuations tend to spike precisely when specific macro conditions align with particular public market movements. That insight might not be obvious if you're looking at those datasets separately. But at their intersection? That's alpha waiting to be explored.</p>\n<p>The same principle applies across different teams and geographies. When portfolio managers, research analysts, and risk analysts can all feed their data into a shared workspace, the AI becomes a tool for collaborative discovery. It surfaces opportunities that emerge from combinations of perspectives that were previously isolated from each other.</p>\n<p>This is why building a unified workspace where firms can bring their data in from different asset classes, different teams, and different geographies matters so much. It's not just about convenience or consolidation. It's about creating the conditions where humans and AI can collaborate effectively to discover alpha in the intersections where it actually lives.</p>\n<p>And here's something worth keeping in mind: the models are only getting better. They're getting smarter, handling more data, parsing more complexity. The ability to digest and understand massive, unified datasets is not a limitation of future AI, it's just a matter of time.</p>\n<p>The firms that build these integrated workspaces today won't just get the competitive advantage from the tools available right now. <strong>They'll be perfectly positioned to take advantage of the next generation of models that can do even more with all that data.</strong></p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"addressing-the-real-world-complexities\">Addressing the real-world complexities<a href=\"https://didierlopes.com/blog/why-generative-ai-isnt-uncovering-alpha-yet#addressing-the-real-world-complexities\" class=\"hash-link\" aria-label=\"Direct link to Addressing the real-world complexities\" title=\"Direct link to Addressing the real-world complexities\">​</a></h2>\n<p>Although I'm biased, I want to be honest. A unified workspace is a powerful enabler, but it's not a magic wand. Finding alpha still requires the right strategies, the right people, and a willingness to experiment with new combinations of data.</p>\n<p>There's also the matter of integration itself. Bringing all these datasets into one workspace isn't trivial. It requires effort, investment, and a willingness to rethink how data flows through the organization. For many firms, that's a significant lift.</p>\n<p>But here's the thing: <strong>the long-term payoff is worth it</strong>. By bringing disparate datasets together and allowing AI to work alongside your team, firms can unlock insights that were previously hidden.</p>\n<p>The firms that make this investment today, that build truly unified workspaces, will be the ones discovering alpha tomorrow while others are still wrestling with siloed data infrastructure.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"the-path-forward\">The path forward<a href=\"https://didierlopes.com/blog/why-generative-ai-isnt-uncovering-alpha-yet#the-path-forward\" class=\"hash-link\" aria-label=\"Direct link to The path forward\" title=\"Direct link to The path forward\">​</a></h2>\n<p>The future of AI-driven alpha doesn't lie in deploying more AI to individual workflows. It lies in breaking down data silos and building integrated environments where AI can discover patterns at the intersection of datasets.</p>\n<p>A unified workspace is a critical piece of that puzzle, but it's part of a broader toolkit that also involves having the right people, the right strategies, and the right culture of experimentation. It requires firms to rethink their data strategies from the ground up but that shift is essential.</p>\n<p>The invitation is clear: rethink how your data is organized.</p>\n<p>Embrace integrated approaches.</p>\n<p>Consider how a unified workspace can transform AI from a productivity tool into a true source of competitive advantage.</p>\n<p>Truly imagine it.</p>\n<p>The insights, and the alpha, are waiting at the intersections.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"appendix\">Appendix<a href=\"https://didierlopes.com/blog/why-generative-ai-isnt-uncovering-alpha-yet#appendix\" class=\"hash-link\" aria-label=\"Direct link to Appendix\" title=\"Direct link to Appendix\">​</a></h2>\n<p>(Alex is also compiling a list of all AI startups in the financial space, which you can check out <a href=\"https://alexizydorczyk.com/ai-for-hedge-funds.html\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>)</p>\n<p>If I were to segment companies, I would probably segment them as:</p>\n<ol>\n<li>\n<p><strong>Data first companies</strong> - Data Extraction Tools and AI Model Providers (Alpha, Quant, &amp; Forecasting Labs). Selling signals, or derivative is still selling data, it's just - allegedly - more valuable data because it has been processed in a certain way that makes it more valuable. Competing with Bloomberg, S&amp;P, FactSet, ...</p>\n</li>\n<li>\n<p><strong>AI first companies</strong> - Research Copilots (AI \"Analyst\" Assistants) and Excel Copilots (Financial Modeling Aides). They start with AI first and then try to find data relevant to their customers. Competing with OpenAI, Anthropic, ...</p>\n</li>\n<li>\n<p><strong>Infrastructure first companies</strong> - \"Terminal 2.0\" Platforms (Next-Gen Market Terminals). I think examples of the competition is Claude for Financial Services with their MCPs integrations or Blackrock's Aladdin with their new copilot. However, I think that this will always be limiting to create Alpha because if everyone has access to same data and intelligence, then it's hard to find alpha.</p>\n</li>\n</ol>\n<br>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"how-it-started\">How it started<a href=\"https://didierlopes.com/blog/why-generative-ai-isnt-uncovering-alpha-yet#how-it-started\" class=\"hash-link\" aria-label=\"Direct link to How it started\" title=\"Direct link to How it started\">​</a></h3>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-10-28-why-generative-ai-isnt-uncovering-alpha-yet_1.webp\" alt=\"How it started - diagram showing traditional data flow\"></p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"how-its-going\">How it's going<a href=\"https://didierlopes.com/blog/why-generative-ai-isnt-uncovering-alpha-yet#how-its-going\" class=\"hash-link\" aria-label=\"Direct link to How it's going\" title=\"Direct link to How it's going\">​</a></h3>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-10-28-why-generative-ai-isnt-uncovering-alpha-yet_2.webp\" alt=\"How it's going - current state of AI implementation\"></p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"the-future\">The future<a href=\"https://didierlopes.com/blog/why-generative-ai-isnt-uncovering-alpha-yet#the-future\" class=\"hash-link\" aria-label=\"Direct link to The future\" title=\"Direct link to The future\">​</a></h3>\n<p>\"<em>If a strategy with a proven positive alpha becomes public information, its profitability is eroded through market efficiency.</em>\"</p>\n<p>Then, Data + Intelligence needs to happen within organization. And the foundational infra of each of these firms becomes the most important piece.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-10-28-why-generative-ai-isnt-uncovering-alpha-yet_3.webp\" alt=\"The future - integrated workspace vision\"></p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/why-generative-ai-isnt-uncovering-alpha-yet",
            "title": "Why generative AI isn't uncovering alpha yet",
            "summary": "Ken Griffin says AI isn't delivering alpha for hedge funds. He's not wrong, but the problem isn't AI's capability - it's the lack of integrated workspaces.",
            "date_modified": "2025-10-28T00:00:00.000Z",
            "tags": [
                "ai",
                "hedge-funds",
                "alpha",
                "data-integration",
                "finance",
                "generative-ai"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/rethinking-the-financial-interface-in-the-age-of-data-and-intelligence-abundance",
            "content_html": "<p><img decoding=\"async\" loading=\"lazy\" alt=\"Rethinking the financial interface in the age of data and intelligence abundance\" src=\"https://didierlopes.com/assets/images/2025-10-15-rethinking-the-financial-interface-in-the-age-of-data-and-intelligence-abundance-afda2557cb83fac2352f3526473bcfe7.webp\" width=\"421\" height=\"421\" class=\"img_ev3q\"></p>\n<p>How the explosion of data and AI is breaking the old financial terminal monopoly and creating space for open, modular, AI-native interfaces that serve users, not vendors.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>The interface products from data monopolies were never just software; they were monopolies sustained by control. Control over data, pricing, and how professionals accessed information. That control wasn't arbitrary - it was the logical outcome of incentives built around data margins rather than user outcomes.</p>\n<p>But that control is eroding. The explosion of alternative data, the rise of AI agents, and the stubborn focus on selling data over serving users have created a fracture the old model can't contain.</p>\n<p>A new model is emerging: interface-first, data-neutral, and AI-native. A model where the software layer serves the user, not the vendor's data sales team. Where the interface becomes a true operating system for finance: open, modular, and intelligent.</p>\n<p>The shift is structural. And it's being driven by the same forces that once built the terminal, an explosion of data, new forms of intelligence, and an industry that can no longer afford misaligned incentives.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"the-incentive-flip\">The incentive flip<a href=\"https://didierlopes.com/blog/rethinking-the-financial-interface-in-the-age-of-data-and-intelligence-abundance#the-incentive-flip\" class=\"hash-link\" aria-label=\"Direct link to The incentive flip\" title=\"Direct link to The incentive flip\">​</a></h2>\n<p>For decades, financial software bundled everything: the data, the tools, and the user experience. You paid one price for all of it - a package so tightly coupled that you could never separate what you were really paying for.</p>\n<p>That bundle created an empire. But it also created a distortion. Vendors optimized for selling data, not for improving the user experience. Every design choice, from the limited export features to the lack of integration with external datasets, served the protection of data margins.</p>\n<p><strong>A decoupled interface breaks that dynamic.</strong></p>\n<p>Once the UI stands on its own, its incentive flips. A standalone interface doesn't need to protect data entitlements. It only needs to serve the user. Its success depends on usability, speed, and how well it integrates with whatever the analyst already uses - not on how many internal datasets it can upsell.</p>\n<p>The interface becomes an impartial workbench. Analysts can plug in their preferred data sources - proprietary, public, or alternative - and get to work without vendor interference. They stop paying for access to data they don't use and start paying for software that helps them move faster.</p>\n<p>This separation forces competition where it matters most - speed, interoperability, and design - rather than who controls the data contracts. In a world where most professionals already subscribe to multiple feeds, the real value isn't in who sells the data. It's in who helps you make sense of it.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"why-this-moment\">Why this moment<a href=\"https://didierlopes.com/blog/rethinking-the-financial-interface-in-the-age-of-data-and-intelligence-abundance#why-this-moment\" class=\"hash-link\" aria-label=\"Direct link to Why this moment\" title=\"Direct link to Why this moment\">​</a></h2>\n<p>Finance has always been data-driven. But today, it's data-saturated.</p>\n<p>Satellite imagery, credit card transactions, app usage, ESG disclosures, web traffic, social sentiment... New datasets are arriving faster than any incumbent can ingest them. Most of them don't fit neatly into a pre-built terminal. They're messy, dynamic, and often proprietary.</p>\n<p>No closed platform can keep up with this level of diversity. The data landscape has simply outgrown the idea of a single vendor controlling the flow.</p>\n<p><strong>Closed systems once thrived on scarcity; open ones now thrive on abundance.</strong></p>\n<p>What's needed is an open interface, one built like a network. It should treat data as modular and composable, like APIs that can be plugged in and swapped out. Analysts should be able to connect to a new data source, build a model, or run an AI workflow without waiting for a vendor's permission.</p>\n<p>Modern platforms embrace this modularity. They're designed as pipelines rather than products. They see finance as a system of moving parts - some internal, some external, all interoperable. The contrast with legacy systems is stark. A monolithic terminal moves slowly because it's built around the assumption of completeness: that everything you could ever need lives inside its walls. That assumption no longer holds.</p>\n<p><strong>Neutrality becomes a survival strategy, not a philosophy.</strong></p>\n<p>An interface built for neutrality doesn't push one feed, model, or dataset over another; it simply exposes the best tools and lets the user decide. This is the opposite of the incentive structure that has dominated finance for decades. In the old world, every UI was also a distribution channel. Every search result, chart, and default setting subtly guided users toward in-house content.</p>\n<p>A neutral interface ends that. It competes not on exclusivity but on openness. Its job is to make the user's workflow faster, cleaner, and more powerful - not to shape what data they consume. When users can bring any data or tool they want, innovation moves faster. Vendors compete on quality rather than access, and analysts can finally mix the best of everything in one coherent environment. <strong>Their coherent environment, shaped to their workflow.</strong></p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"the-architecture-of-openness\">The architecture of openness<a href=\"https://didierlopes.com/blog/rethinking-the-financial-interface-in-the-age-of-data-and-intelligence-abundance#the-architecture-of-openness\" class=\"hash-link\" aria-label=\"Direct link to The architecture of openness\" title=\"Direct link to The architecture of openness\">​</a></h2>\n<p>If you follow this logic to its conclusion, an open, extensible, AI-native interface becomes something larger than an app. <strong>It becomes the operating system of finance.</strong></p>\n<p>Like a computer OS, it provides a unified environment for every tool, every dataset, every agent. In this world, an analyst doesn't open five different applications. They open the same workspace every morning, and it is their environment. It holds their context, connects to their data, and runs their automations &amp; workflows.</p>\n<p>Building this requires solving three hard problems:</p>\n<p><strong>The data problem:</strong> Ingesting structured and unstructured data at enterprise scale while maintaining governance and latency.</p>\n<p><strong>The interface problem:</strong> Designing a UX flexible enough for research, analytics, and reporting without having the user leaving the platform.</p>\n<p><strong>The ecosystem problem:</strong> Convincing vendors, users, and developers to build on top of it rather than around it.</p>\n<p>That's why few have tried. And why those who do will define the next generation of financial software.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"extensibility-the-expression-of-freedom\">Extensibility: the expression of freedom<a href=\"https://didierlopes.com/blog/rethinking-the-financial-interface-in-the-age-of-data-and-intelligence-abundance#extensibility-the-expression-of-freedom\" class=\"hash-link\" aria-label=\"Direct link to Extensibility: the expression of freedom\" title=\"Direct link to Extensibility: the expression of freedom\">​</a></h3>\n<p>Modern analysts don't just consume data; they create it. Every model, notebook, and internal database is a new form of proprietary signal. A next-generation interface needs to treat that as first-class input.</p>\n<p><strong>Bring your own data.</strong> Analysts can connect internal systems - their Snowflake warehouse, their portfolio data, or even unstructured files like research memos - and blend them seamlessly with vendor data. No conversions, no export limits, no awkward detours through Excel.</p>\n<p><strong>Bring your own agent.</strong> The analyst can integrate their own intelligence layer. One day it might be a general-purpose LLM; the next, a fine-tuned model that excels at analyzing FOMC minutes. The interface shouldn't care. It should provide an open protocol for intelligence - where agents and tools can be orchestrated together without friction.</p>\n<p><strong>Bring your own workflow.</strong> This is where data, models, and agents converge to automate complex, multi-step tasks - like drafting an investment memo, building a risk dashboard, or monitoring credit exposures. A workflow is no longer a hard-coded process inside a terminal; it's something the analyst defines. You might start with your firm's internal data, enrich it with a vendor's ESG feed, and pass both through an AI agent that writes the first draft of your memo - all within the same interface. The workflow can then route the output to a colleague for review, trigger an update in a dashboard, or feed the result into another model.</p>\n<p>Extensibility is no longer a technical feature, it's the expression of freedom inside the software.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"intelligence-context-as-currency\">Intelligence: context as currency<a href=\"https://didierlopes.com/blog/rethinking-the-financial-interface-in-the-age-of-data-and-intelligence-abundance#intelligence-context-as-currency\" class=\"hash-link\" aria-label=\"Direct link to Intelligence: context as currency\" title=\"Direct link to Intelligence: context as currency\">​</a></h3>\n<p>An AI-native interface isn't a chat window. It's an environment that understands context, remembers state, and reacts to changes. It's aware of your portfolio, your preferences, your recent queries, and even your compliance boundaries. It can reason across multiple data sources and agents - not by pretending to know everything, but by knowing how to connect to everything.</p>\n<p>In this world, context becomes currency: the better your interface understands it, the smarter every workflow becomes.</p>\n<p>This demands event-driven architecture. Legacy systems were designed around menus and files; AI-native systems are built around events and context. Every user interaction carries metadata: who asked, about what, under what constraints. Every answer links back to its provenance. The system becomes self-documenting - every step traceable, every output auditable.</p>\n<p>And because it's event-driven, it's always on. The interface doesn't wait for you to ask \"what changed overnight?\" - it tells you. It doesn't wait for you to open a chart, it updates it as new data arrives. The interface becomes a living environment. It evolves with you, learning from every query, refining context, and surfacing insights before you ask.</p>\n<p>The shift to this financial software OS will move even faster with AI, not because AI is flashy, but because it turns the entire system into an alpha-generating machine. Every integrated data source becomes a signal. Every workflow becomes repeatable edge. The interface doesn't just help you find alpha; it compounds it.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"beyond-hedge-funds\">Beyond hedge funds<a href=\"https://didierlopes.com/blog/rethinking-the-financial-interface-in-the-age-of-data-and-intelligence-abundance#beyond-hedge-funds\" class=\"hash-link\" aria-label=\"Direct link to Beyond hedge funds\" title=\"Direct link to Beyond hedge funds\">​</a></h2>\n<p>This transformation isn't limited to the quant elite. It's spreading across the entire industry.</p>\n<p>Every firm, from asset managers to corporate treasuries, now operates in a multi-data world. Analysts are technically literate, often fluent in Python, and increasingly empowered by AI. Non-developers can build small automations or workflows that once required entire IT teams. The power dynamic is shifting from vendor-driven tools to user-driven environments.</p>\n<p>Meanwhile, the open-source ecosystem has exploded. Powerful financial libraries, AI agents, and visualization frameworks are freely available. The infrastructure that once cost millions can now be assembled by a small team.</p>\n<p>The monopoly of access has collapsed. Firms no longer want to rent the same interface as their competitors; they want to own their workflows. The transition won't be smooth. But the pattern is clear: openness outcompetes control. Modular systems outpace monoliths. And the users, now more empowered than ever, are driving the change themselves.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"the-path-forward\">The path forward<a href=\"https://didierlopes.com/blog/rethinking-the-financial-interface-in-the-age-of-data-and-intelligence-abundance#the-path-forward\" class=\"hash-link\" aria-label=\"Direct link to The path forward\" title=\"Direct link to The path forward\">​</a></h2>\n<p>The story of financial software has always been a story about control. Who controls the data, who controls the interface, who controls the user experience.</p>\n<p>That control is now up for grabs.</p>\n<p>The winners of the next era won't be those who hoard data, but those who make it usable. They'll build interfaces that adapt, not entrap. They'll align incentives with users, not against them.</p>\n<p>And they'll understand that a true financial OS isn't built in isolation, it's built in community.</p>\n<p>Open ecosystems matter. A modern financial interface needs an open developer base to grow new connectors, agents, and applications organically. It needs users contributing back to the system, expanding its capabilities faster than any single company could.</p>\n<p>This is exactly what we're building at OpenBB. An open, AI-native workspace that's data-neutral by design. A platform that integrates seamlessly with any dataset, any model, any agent. A financial operating system that's not owned by a data vendor, but powered by its users.</p>\n<p>Soon, we'll announce the <a href=\"https://github.com/OpenBB-finance/OpenBB\" target=\"_blank\" rel=\"noopener noreferrer\">Open Data Platform</a> which is the largest open source project in the finance category, proof that the appetite for neutrality, openness, and innovation is real. And as the ecosystem grows, every new connector, every new AI agent, every new app built by the community compounds the network effect.</p>\n<p>The era of walled-garden financial software is ending.</p>\n<p>The next generation of financial software won't sell you data, it will give you power.</p>\n<p><strong>The interface is striking back.</strong></p>\n<p>And this time, it's on the user's side.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/rethinking-the-financial-interface-in-the-age-of-data-and-intelligence-abundance",
            "title": "Rethinking the financial interface in the age of data and intelligence abundance",
            "summary": "How the explosion of data and AI is breaking the old financial terminal monopoly and creating space for open, modular, AI-native interfaces that serve users, not vendors.",
            "date_modified": "2025-10-15T00:00:00.000Z",
            "tags": [
                "finance",
                "interface",
                "ai",
                "data",
                "openbb",
                "financial-software",
                "terminals",
                "technology"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/the-hidden-incentive-war-behind-financial-terminals",
            "content_html": "<p><img decoding=\"async\" loading=\"lazy\" alt=\"The hidden incentive war behind financial terminals\" src=\"https://didierlopes.com/assets/images/2025-10-08-the-hidden-incentive-war-behind-financial-terminals-cb8616d993b85cea7575eac8f1c6085c.webp\" width=\"421\" height=\"421\" class=\"img_ev3q\"></p>\n<p>How the misalignment between data providers and interface builders creates friction for users - the hidden conflict between selling data and serving users in financial software.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>I've spent years building and learning about financial software, and I've come to understand how big of a misalignment there is between data providers and interface builders. In simpler terms, companies that sell financial data also build the software (workspaces, terminals, interfaces) that professionals use, but their goals for the data often clash with what users need from the interface.</p>\n<p>This misalignment operates quietly behind the scenes, yet it affects everything from product features to user workflows. In this first part of a two-part series, I want to unpack this conflict from my perspective, to shed light on why these tools often feel clunky despite sky-high prices.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"why-the-all-in-one-model-made-sense-until-it-didnt\">Why the all-in-one model made sense (until it didn't)<a href=\"https://didierlopes.com/blog/the-hidden-incentive-war-behind-financial-terminals#why-the-all-in-one-model-made-sense-until-it-didnt\" class=\"hash-link\" aria-label=\"Direct link to Why the all-in-one model made sense (until it didn't)\" title=\"Direct link to Why the all-in-one model made sense (until it didn't)\">​</a></h2>\n<p>To understand why this gap runs so deep, it helps to look at how the current model came to be.</p>\n<p>A few decades ago, the \"all-in-one terminal\" was a brilliant solution to a real problem. Financial data was scarce, fragmented, and technically hard to distribute. Building a single platform that bundled real-time prices, analytics, chat, research, and trading in one environment was revolutionary. It created a flywheel: the more professionals used it, the more indispensable it became. Every new user made the network more valuable; every new data feed reinforced the platform's position.</p>\n<p>That success baked in an assumption: the same company should own both the data and the interface. At the time, that made perfect sense. Integration guaranteed speed, consistency, and trust. Clients didn't want to juggle APIs; they wanted one screen where everything just worked. For decades, that was the winning formula, and the incentives were aligned, the vendor got paid for data, and the user got reliability.</p>\n<p>But the world changed. Data exploded. APIs became cheap and ubiquitous. Firms started generating their own proprietary datasets, and new categories of alternative data - web traffic, satellite imagery, sentiment, transactions - appeared faster than any one vendor could absorb. The interface was no longer the bottleneck; the business model was.</p>\n<p>The incumbents stayed optimized for the old equilibrium: control all the data, protect the margins, keep the user inside.</p>\n<p>That's the problem. What was once an elegant way to simplify complexity has become a structural drag on innovation. The all-in-one design isn't broken because it's unified; it's broken because it's closed. Every decision about openness or interoperability now runs through the same filter: \"Will this threaten our data revenue?\"</p>\n<p>At a high level, the data vendors are primarily optimized to protect and grow their data profit streams, while the ideal interface should be optimized to reduce user friction and empower workflow flexibility. These two priorities collide constantly. The result is interfaces that are frequently restricted or designed in ways that favor the vendor's bottom line over the user's experience.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"how-data-vendors-guard-the-golden-goose\">How data vendors guard the golden goose<a href=\"https://didierlopes.com/blog/the-hidden-incentive-war-behind-financial-terminals#how-data-vendors-guard-the-golden-goose\" class=\"hash-link\" aria-label=\"Direct link to How data vendors guard the golden goose\" title=\"Direct link to How data vendors guard the golden goose\">​</a></h2>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"act-1-what-users-see\">Act 1: What users see<a href=\"https://didierlopes.com/blog/the-hidden-incentive-war-behind-financial-terminals#act-1-what-users-see\" class=\"hash-link\" aria-label=\"Direct link to Act 1: What users see\" title=\"Direct link to Act 1: What users see\">​</a></h3>\n<p>Financial data is extremely lucrative. Major market data providers enjoy operating profit margins that tech-only product companies can only dream of. Selling data is a high-margin business because once it's collected and cleaned, reselling it to additional customers costs very little. Also consider how many employees at these firms are based offshore or in low-cost centers, further boosting margins.</p>\n<p>This sets up a clear incentive: data vendors will do almost anything to protect that high-margin data business. And \"almost anything\" often includes holding back their own interface capabilities to avoid giving away too much value without additional payment.</p>\n<p>One common tactic is imposing caps and friction on data usage in their flagship software. A financial desktop app may limit how much data you can export each month - hit the cap and you're stuck waiting until next month unless you pay for a more expensive package.</p>\n<p>I first knew about these limits because it was one of the biggest complaints I heard in our early user interviews. Later, I met someone who used to work at one of these big incumbents. Their job was monitoring each client's data usage, cutting them off when they exceeded certain limits, and then calling them to understand what they were doing with \"too much\" data. They eventually quit because they felt it was morally wrong to hamstring clients like that. But this story shows the extent of guarding the golden goose.</p>\n<p>These caps and throttles are not accidental; they're deliberate choices to funnel users into higher-priced data plans or premium products. If you exceed your data-export limit for the month, no one in your firm can download any more data until the next month's reset. You can imagine how infuriating it is to be cut off mid-workflow. But from the vendor's perspective, it's protecting the golden goose of data revenue.</p>\n<p>Another way vendors guard their data P&amp;L is by creating friction to bring external data in. In theory, you'd want your analytics workspace to ingest any data you have - proprietary models, alternative datasets - and let you see everything in one place.</p>\n<p>But there's basically no such thing as \"bring your own data\" to the interface of a traditional data vendor. They are a data business. The interface is just a distribution mechanism, and the vendor is only incentivized to make that interface great as long as it results in more of their data being sold. That doesn't include letting clients easily plug in data from outside sources. This keeps clients dependent on the vendor's own data offerings and prevents any third-party data or tools from diluting the value of the vendor's ecosystem.</p>\n<p>Case in point: I recently talked with one of the big incumbents about getting access to their MCP Server. The discussion with their sales team quickly jumped into use cases. I explained that I just wanted to enable our mutual clients to access the vendor's data via our workspace (i.e. using our interface to consume data they're already entitled to). Their response was that they needed to learn more about the use case because \"We don't want to take a hit on the market share of our desktop interface\". In other words, they were worried that if clients can get the data through any interface other than the vendor's own, it would cannibalize their desktop business.</p>\n<p>This is the incentive conflict in action, the vendor protecting its data (and the interface lock-in around that data) at the direct expense of user flexibility.</p>\n<p>It gets worst, most of these large data vendors don't even make all of their own datasets available on their flagship desktop applications. They'll happily sell you the interface as a gateway to their data, but then you discover you can't even get all their feeds through that gateway. If you need one of those \"off-platform\" datasets, you might have to buy it separately and access it through a completely different channel or API.</p>\n<p>All of these are designed to protect data revenue.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"act-2-why-it-happens-inside-the-company\">Act 2: Why it happens (inside the company)<a href=\"https://didierlopes.com/blog/the-hidden-incentive-war-behind-financial-terminals#act-2-why-it-happens-inside-the-company\" class=\"hash-link\" aria-label=\"Direct link to Act 2: Why it happens (inside the company)\" title=\"Direct link to Act 2: Why it happens (inside the company)\">​</a></h3>\n<p>The restrictions users feel externally are battles the interface team lost internally.</p>\n<p>Inside large financial data firms, there's frequently a tug-of-war between the data business and the interface product team. Imagine you work at one of these incumbents and you suggest an improvement to the interface for a specific workflow. The first question from management will be: How will this result in more data sales?</p>\n<p>It gets trickier when you're up against a PM on the data team who's suggesting adding a new data feed that could be packaged and sold. The data teams are the revenue engines of the company, so they get to call the shots. The desktop/interface team has the less glamorous task of maintaining and incrementally improving a mature software product that, in many cases, hasn't fundamentally changed in years.</p>\n<p>Here's a scenario: the interface team proposes a new feature, a way for users to seamlessly import their own CSV data into the platform to chart or analyze alongside the vendor's data. It's technically feasible and would make users very happy. But implementing it might mean users don't need to buy the vendor's extended historical data package (because they could import an alternative source they already have). The proposal gets watered down or vetoed by the data side, which argues it \"cannibalizes\" the product offerings.</p>\n<p>From the outside, clients just see a slow, clunky interface that never seems to embrace obvious conveniences like modern import/export tools or collaboration features. From the inside, it's a story of the higher-margin business overriding the user-experience improvements. The interface team might be banging the drum for usability, but the data team is banging the drum for revenue.</p>\n<p>Another angle to this internal friction is how products are sold. A client might really only want to buy a raw data feed (skipping the fancy desktop software), because maybe they have their own analytics platform. But the desktop sales reps have quotas tied to selling the desktop product. If a big client opts to pay only for data and not for the interface, the desktop sales team misses out on their numbers (and likely their commissions). This leads to absurd situations where the company has an internal debate about what to offer the client, even if the client's preference is clear, simply because selling data alone could \"undermine\" the desktop business's targets. Different teams have conflicting goals.</p>\n<p>It's not that the people running these companies are clueless about UX or blind to user needs; it's that they are conflicted. When push comes to shove, protecting the lucrative data revenue will win over improving the interface every time. These firms have essentially set up an internal hierarchy where data is king and UX is a second-class citizen.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"act-3-the-economic-reality-why-this-hierarchy-exists\">Act 3: The economic reality (why this hierarchy exists)<a href=\"https://didierlopes.com/blog/the-hidden-incentive-war-behind-financial-terminals#act-3-the-economic-reality-why-this-hierarchy-exists\" class=\"hash-link\" aria-label=\"Direct link to Act 3: The economic reality (why this hierarchy exists)\" title=\"Direct link to Act 3: The economic reality (why this hierarchy exists)\">​</a></h3>\n<p>These internal battles aren't random politics, they reflect a deeper economic reality.</p>\n<p>This economic imbalance between data and interface products is key to understanding many design decisions (or lack thereof) in financial software. Simply put, data scales, software doesn't (as much).</p>\n<p><strong>Data products</strong> (feed subscriptions, specialty datasets) scale incredibly well. Once the data is collected, cleaned, and stored, selling it to one more customer costs almost nothing. Each additional sale is nearly pure profit, so these businesses boast exceptionally high margins.</p>\n<p><strong>Interface products</strong> (analytics workstations, charting applications, desktop terminals) behave like typical software. You need engineers to build new features, you need a support team to help users, there's ongoing maintenance and infrastructure - and it's hard to charge $30k/y per seat for UI. The margins here are much thinner.</p>\n<p>Many incumbents recognize this and actually bundle the software as long as you're really paying for the data underneath. Buy the data feeds, and consume it via desktop platform. This bundling obscures a reality: if you isolated the interface itself, users probably wouldn't be willing to pay very much for it. The willingness-to-pay resides in the data.</p>\n<p>The result is that every roadmap decision for the interface is filtered through a revenue lens. Does adding a certain feature help sell more high-margin data? If yes, do it. If not (i.e., it \"just\" improves user experience but doesn't clearly drive new data subscriptions), it'll get de-prioritized or scrapped. This is why you see seemingly obvious usability improvements left untouched for years.</p>\n<p>For instance, adding a slick code editor might be low-hanging fruit technically - lots of users would love to script and automate tasks. But if that encourages power users to pull data out of the platform (potentially bypassing some paid service or exposing data externally), it won't get much love internally. Conversely, adding yet another dataset (say an ESG scores package, or some new analytics feed) gets a big marketing push because it's a new SKU to sell.</p>\n<p>The net effect of all this is a status quo where the interfaces feel archaic and user-unfriendly across the board. Not coincidentally, these vendors have barely budged on pricing or profitability for decades. In a truly competitive, user-centric market, one might expect a slick, modern UX at a lower price by now - but the incentive structure has kept competition at bay and kept vendors squarely focused on milking data profits via bundled interfaces.</p>\n<p>Now the pattern is clear. What looks like user-hostile design (Act 1) is actually the outcome of internal power dynamics (Act 2) driven by margin economics (Act 3).</p>\n<p><strong>This isn't incompetence - it's rational profit maximization under a specific business model.</strong></p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"why-this-persists\">Why this persists<a href=\"https://didierlopes.com/blog/the-hidden-incentive-war-behind-financial-terminals#why-this-persists\" class=\"hash-link\" aria-label=\"Direct link to Why this persists\" title=\"Direct link to Why this persists\">​</a></h2>\n<p>A natural question is: Why haven't upstart competitors disrupted this model with a more user-friendly alternative?</p>\n<p>One reason competition has been so stagnant is that the incumbents have a habit of doubling down on their data dominance through acquisitions. Look at the acquisition history of any major financial data vendor, and a pattern emerges: they almost always buy other data companies or content sources, not interface innovators. If a smaller company comes along with a valuable new dataset, data feed, or unique analytics content, the big players snap it up and fold that data into their empire (often keeping it exclusive to their platform). They rarely, if ever, acquire companies that innovate on the UI/UX layer.</p>\n<p>This consolidation strategy means the big vendors keep enriching their data catalog (and strengthening their data monopoly) while the actual software interface remains largely the same. This prevents serious competition on the data front, which in turn protects the interface from outside disruption (because any would-be challenger would need comparable data to be useful).</p>\n<p>A startup might create a beautiful, modern analytics interface, but without the breadth of data that the incumbents offer, it's hard to convince users to switch. And if a startup focuses on building a unique dataset, one of the big vendors will likely either imitate it quickly or offer to acquire the upstart. The result is a kind of data monopoly flywheel. The big players keep getting bigger by absorbing new data sources, which raises the barrier to entry for anyone else.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"incentives-shape-everything-and-change-is-coming\">Incentives shape everything (and change is coming)<a href=\"https://didierlopes.com/blog/the-hidden-incentive-war-behind-financial-terminals#incentives-shape-everything-and-change-is-coming\" class=\"hash-link\" aria-label=\"Direct link to Incentives shape everything (and change is coming)\" title=\"Direct link to Incentives shape everything (and change is coming)\">​</a></h2>\n<p>The conflict between data monetization and interface usability is the quiet force that has shaped financial software for decades. Data vendors have been optimized to protect their margins; interfaces should be optimized to reduce user friction - but when one company controls both, guess which priority wins out?</p>\n<p>We've been living in a world where the firms selling data also control the interface through which analysts access it, and they've designed that interface (consciously or not) as a sort of toll booth. It's not that these platforms provide no value - on the contrary, they deliver enormous value, but it's value delivered on the vendor's terms. Users feel the friction daily: the inability to easily mix in a new data source, the archaic workflows that never improve, the upsell pop-ups or usage limits that remind us who's really in charge.</p>\n<p>The key point here is that this misalignment isn't due to some cluelessness or malice on the part of the companies; it's an incentive problem baked into a legacy business model. Understanding that is crucial. The vendor isn't necessarily trying to make it terrible, they're just not that incentivized to make it much better.</p>\n<p>And indeed, change is afoot. We're starting to see the early signs of a shift in this model. In the next part of this series, I'll dive into how a new approach - a pure-interface model decoupled from data sales - could realign incentives in favor of the user.</p>\n<p>In other words, what if the company that builds your interface has no stake in selling you data?</p>\n<p>Could that lead to a truly user-centric financial workspace?</p>\n<p>I believe it can, and I'm excited to explore that in Part II.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/the-hidden-incentive-war-behind-financial-terminals",
            "title": "The hidden incentive war behind financial terminals",
            "summary": "How the misalignment between data providers and interface builders creates friction for users - the hidden conflict between selling data and serving users in financial software.",
            "date_modified": "2025-10-08T00:00:00.000Z",
            "tags": [
                "finance",
                "financial-terminals",
                "data",
                "incentives",
                "business-model",
                "ux",
                "bloomberg",
                "interfaces"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/the-evolution-of-ai-agents-in-finance",
            "content_html": "<p><img decoding=\"async\" loading=\"lazy\" alt=\"The Evolution of AI Agents in Finance\" src=\"https://didierlopes.com/assets/images/2025-09-23-the-evolution-of-ai-agents-in-finance-763735716419bdd5623ad1fd4249ec4c.webp\" width=\"762\" height=\"421\" class=\"img_ev3q\"></p>\n<p>Mapping the evolution of AI agents in finance from ChatGPT wrappers to derived data insights - and why the real value is shifting from interfaces to intelligence.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"introduction\">Introduction<a href=\"https://didierlopes.com/blog/the-evolution-of-ai-agents-in-finance#introduction\" class=\"hash-link\" aria-label=\"Direct link to Introduction\" title=\"Direct link to Introduction\">​</a></h2>\n<p>In late 2022, OpenAI's ChatGPT burst onto the scene and immediately captured the attention of finance. Almost overnight, the industry recognized that generative AI could dramatically speed up data-gathering, research, and analysis.</p>\n<p>What started as a buzz around a clever chatbot quickly ignited an arms race: How could we harness this \"pure\" AI intelligence specifically for finance?</p>\n<p>This essay maps the acceleration of AI agents in finance, from wrapping ChatGPT around financial datasets in the early days to deep data integrations and emerging standards now. I wrap up by laying out where I believe this is heading.</p>\n<p><em>Spoiler: the game is changing, and the real value in finance AI is shifting from fancy chat interfaces to the derived data insights those interfaces can produce.</em></p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"phase-1-chatgpt-wrappers-on-open-and-public-data\">Phase 1: ChatGPT wrappers on open and public data<a href=\"https://didierlopes.com/blog/the-evolution-of-ai-agents-in-finance#phase-1-chatgpt-wrappers-on-open-and-public-data\" class=\"hash-link\" aria-label=\"Direct link to Phase 1: ChatGPT wrappers on open and public data\" title=\"Direct link to Phase 1: ChatGPT wrappers on open and public data\">​</a></h3>\n<p>The first phase of this evolution saw nimble startups harnessing AI models to make sense of <em>publicly available</em> financial information. Using APIs and open datasets, these innovators built AI assistants that could, for example, pull stock prices, scrape financial news, or parse SEC filings and then answer questions or generate basic analyses.</p>\n<p>This was the era of taking off-the-shelf AI and wrapping it around well-known data sources like EDGAR or even Yahoo Finance.</p>\n<p>The beauty of Phase 1 was <strong>accessibility</strong>: anyone could access the same public data, so a small startup could create a financial research chatbot without needing special partnerships. Or even a big budget, as most of the cost was on the inference.</p>\n<p>Nonetheless, these early AI agents demonstrated that even with common data, AI could deliver value by digesting mountains of information in seconds - summarizing earnings reports or comparing company metrics on the fly - tasks that would take humans hours or days.</p>\n<blockquote>\n<p>The defining feature of Phase 1 was <strong>speed of access</strong>: information that once required hours or days of work could suddenly be retrieved and synthesized in seconds.</p>\n</blockquote>\n<br>\n<p>However, because they relied only on public data, their insights were often not unique; every competitor had access to the same information. This meant that while Phase 1 proved AI's potential in finance, it also highlighted the next challenge: how to go beyond the readily available data to gain deeper, proprietary insights.</p>\n<p>At the end of this phase, Perplexity showed up. They saw the value on the public open data, but didn't keep it to a few datasets. They connected LLMs to the entire web and focused on that one feature.</p>\n<p>They pioneered the concept of \"getting answers\" from search as opposed to links. The next step after search.</p>\n<p>So at the end of this phase, an analyst's AI assistant wasn't limited to static training data or a fixed library of filings; it could pull the latest news, prices, and research from the entire internet - on-the-go.</p>\n<p>But web search was never meant to be a product, but a feature.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"phase-2-big-labs-add-web-search\">Phase 2: Big labs add web search<a href=\"https://didierlopes.com/blog/the-evolution-of-ai-agents-in-finance#phase-2-big-labs-add-web-search\" class=\"hash-link\" aria-label=\"Direct link to Phase 2: Big labs add web search\" title=\"Direct link to Phase 2: Big labs add web search\">​</a></h3>\n<p>While Perplexity gained a lot of market share due to the time it took big labs to add this feature, they effectively caught up.</p>\n<p>For finance, this was revolutionary: market conditions change by the minute, and being able to retrieve up-to-the-moment information meant AI assistants could provide far more relevant answers. An investor could ask an AI agent about today's Federal Reserve announcement or a rumor affecting a stock, and the agent would actually go out, search the web, and return with an answer.</p>\n<p>This phase expanded the AI's knowledge horizon dramatically, turning these systems into dynamic <em>research analysts</em> that weren't confined by a knowledge cutoff OR by the embedding chunks that the startup had in their vector database.</p>\n<blockquote>\n<p>The defining feature of Phase 2 was <strong>breadth of access</strong>: instead of being limited to a handful of sources, AI agents could now reach across the entire internet.</p>\n</blockquote>\n<br>\n<p>It did introduce new challenges, like ensuring the information found was reliable and managing the complexity of searching and reasoning on the fly, but overall Phase 2 proved that giving AI agents the tools to access external data made them significantly more powerful and context-aware.</p>\n<p>Startups understood that they would need to narrow down one step further, and they couldn't conquer the world. AI labs were coming to eat their lunch after all.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"phase-3-integrating-proprietary-vendor-data\">Phase 3: Integrating proprietary vendor data<a href=\"https://didierlopes.com/blog/the-evolution-of-ai-agents-in-finance#phase-3-integrating-proprietary-vendor-data\" class=\"hash-link\" aria-label=\"Direct link to Phase 3: Integrating proprietary vendor data\" title=\"Direct link to Phase 3: Integrating proprietary vendor data\">​</a></h3>\n<p>As the space heated up, financial AI startups sought new ways to differentiate. The obvious next step was going beyond public web data into <em>proprietary financial datasets</em> held by incumbent data vendors.</p>\n<p>Instead of just parsing SEC filings (which anyone can get), why not plug into premium data like analyst ratings from Morningstar, credit data from rating agencies, or rich financials from FactSet?</p>\n<p><strong>This phase saw startups forging partnerships with data providers to narrow their focus on high-value content not freely available on the open web</strong>.</p>\n<p>For example, Perplexity announced integrations allowing subscribers with a FactSet or Crunchbase account to query those databases through its AI. FactSet's own product team embraced this, noting that providing their trusted data via Perplexity's AI research tool created an \"open, flexible ecosystem\" for clients.</p>\n<p>In practice, these deals meant an AI assistant could now answer questions not just from public info, but from paid datasets (e.g. <em>\"What's the 5-year EBITDA CAGR of all companies in the S&amp;P 500, according to FactSet?\"</em>).</p>\n<blockquote>\n<p>The defining feature of Phase 3 was <strong>depth of access</strong>: moving from shallow, open information to rich proprietary datasets that offered a competitive edge.</p>\n</blockquote>\n<br>\n<p>Startups that secured such partnerships gained an edge, effectively becoming one-stop research copilots.</p>\n<p>However, this shift brought new <em>challenges</em>: accessing vendor data is expensive and requires legal agreements, and the AI's answers are only as good as the data plugged into it.</p>\n<p>Nevertheless, the trend was clear - the most advanced finance chatbots were those tapping into <strong>incumbent data vendors' proprietary troves</strong>, not just the free internet.</p>\n<p>Funnily enough, these big data vendors started having to have interesting discussions internally. On the one hand, they are a data business - so selling data to startups makes sense. But startups are creating derived data essentially (via answers to user prompts) so that creates a conflict of interest with their desktop businesses.</p>\n<p>Ultimately, if a big data vendor has an AI agent on top of their fundamentals datasets that can be accessed from their desktop app, and they are selling that same underlying data to a startup that has an AI agent on top of that data, … something has to give. This is a zero sum game.</p>\n<p>BUT. Data vendors actually have everything to win by forging these relationships. They are slow moving, risk averse but have capital, distribution and ultimately, the main asset: the data. So for them it actually makes sense to partner with nimble startups that are bold, innovative and have nothing to lose. If nothing else, as R&amp;D to understand the size of the market and for M&amp;A (more on this later).</p>\n<p>The main friction point that startups have here is that these datasets from big vendors are very pricey (particularly because they are redistributing this derived data) so they can only select 1 or 2 vendors to work with and consume a subset of their datasets. But also because the APIs between these vendors varies drastically.</p>\n<p>Only if there was some sort of standard…</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"phase-4-anthropic-introduces-mcp\">Phase 4: Anthropic introduces MCP<a href=\"https://didierlopes.com/blog/the-evolution-of-ai-agents-in-finance#phase-4-anthropic-introduces-mcp\" class=\"hash-link\" aria-label=\"Direct link to Phase 4: Anthropic introduces MCP\" title=\"Direct link to Phase 4: Anthropic introduces MCP\">​</a></h3>\n<p>Phase 4 was the moment the game changed. Anthropic unveiled the Model Context Protocol (MCP) - and in doing so, they deliberately erased an entire category of startups.</p>\n<p>MCP is an open standard that lets AI assistants securely interface with any company's data or tools in a plug-and-play way. Instead of a bespoke integration for every vendor, firms can spin up an MCP \"server,\" and any compliant AI model can consume that data instantly. For finance, this meant that a provider like FactSet or PitchBook could wire their proprietary dataset straight into Claude, bypassing the need for a third-party startup to sit in the middle.</p>\n<p>And Anthropic open-sourced it. That wasn't just generosity, it was strategy. By making integration a commodity, they torched the moat that dozens of AI-finance startups had built their businesses around. What used to take a year of engineering and a venture round to fund could now be done with a weekend project and a config file. The \"we connect LLMs to financial data\" pitch evaporated almost overnight.</p>\n<blockquote>\n<p><em>The defining feature of Phase 4 was</em> <strong><em>ease of access</em></strong><em>: what once required expensive, custom integrations was suddenly standardized and commoditized.</em></p>\n</blockquote>\n<br>\n<p>The labs moved fast to prove the point. Anthropic launched Claude for Financial Services, preloaded with FactSet fundamentals, Morningstar valuations, PitchBook private markets data, and S&amp;P Capital IQ transcripts - all natively accessible inside Claude.</p>\n<p>The pattern was clear: <strong>the labs weren't going to verticalize into finance, they were going to hollow out the startups by giving vendors a universal port into their intelligence.</strong></p>\n<p>This was the classic big-tech play: <strong>commoditize your complements</strong> (read <a href=\"https://www.joelonsoftware.com/2002/06/12/strategy-letter-v/\" target=\"_blank\" rel=\"noopener noreferrer\"><strong>Joel on Software Strategy Letter V</strong></a>). The complements here were the connectors, the painstaking integrations that startups had built to justify their existence. By turning those into a free, open standard, Anthropic ensured that the value flowed not to the wrappers, but to the intelligence itself. Labs want one thing above all: for their models to be the default intelligence powering every workflow.</p>\n<p>And the best way to make that happen was to nuke the integration moat and let data vendors plug in directly.</p>\n<p>What happens when you have access to raw intelligence and can connect data from any big data vendor via MCP to it?</p>\n<p>Again:</p>\n<p>Startups understood that they would need to narrow down one step further, and they couldn't conquer the world. AI labs were coming to eat their lunch after all.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"phase-5-from-interfaces-to-insights-derived-data\">Phase 5: From Interfaces to Insights (Derived Data)<a href=\"https://didierlopes.com/blog/the-evolution-of-ai-agents-in-finance#phase-5-from-interfaces-to-insights-derived-data\" class=\"hash-link\" aria-label=\"Direct link to Phase 5: From Interfaces to Insights (Derived Data)\" title=\"Direct link to Phase 5: From Interfaces to Insights (Derived Data)\">​</a></h3>\n<p>Once MCP commoditized integrations, startups were forced to narrow their scope. They leaned into very specific problems: an agent to prep earnings decks, an agent to monitor ESG disclosures, an agent for company meetings. Useful, yes - but inherently smaller markets. This narrowing was the survival play: carve out niches that the frontier labs wouldn't immediately prioritize.</p>\n<p>But firms quickly revealed what they actually valued. They didn't want to spend their time inside yet another agentic interface, watching an AI chain steps together. They wanted <strong>deterministic-like outputs</strong> from those workflows, clean, machine-generated insights that could slot directly into their existing data pipelines. Instead of asking an agent a generic question about the semi-conductor industry and then following-up on that, they wanted a report that talked about everything they should know the about semi-conductor, including replying to questions that they didn't know they should be asking.</p>\n<p>In other words: <strong>derived data.</strong> Not a conversation, not a demo of agentic reasoning, but something as tangible and consumable as a sentiment feed, a risk signal, or a proprietary factor dataset.</p>\n<p>This was the pivot.</p>\n<blockquote>\n<p>The defining feature of Phase 5 was <strong>intelligence on access</strong>: not just reaching data, but transforming it into structured, consumable insights that could flow directly into existing pipelines.</p>\n</blockquote>\n<br>\n<p>The real prize wasn't building the workflow, it was productizing its <strong>outputs</strong>.</p>\n<p>Phase 5 marks the moment when value shifted from the <em>experience</em> of interacting with an AI agent to the <strong>data exhaust</strong> those agents produce.</p>\n<p>Startups that recognized this started selling not \"AI copilots\" but new, machine-synthesized datasets that looked and felt like traditional vendor products, only built by AI.</p>\n<p>But this raises a new question: if multiple providers generate competing research reports on TSMC, how does a firm evaluate which one is best? Add another agent to compare them? Sounds inception-ish. At some point, the human backstop becomes essential, especially in domains where there is no single \"right\" answer. In practice, this means the first wave of derivative data will deliver significant value, but as competition intensifies, advantage may once again shift toward those with privileged or proprietary sources. Or to a workspace that can handle these…</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"my-take-on-where-we-are-heading\">My take on where we are heading<a href=\"https://didierlopes.com/blog/the-evolution-of-ai-agents-in-finance#my-take-on-where-we-are-heading\" class=\"hash-link\" aria-label=\"Direct link to My take on where we are heading\" title=\"Direct link to My take on where we are heading\">​</a></h2>\n<p>Given these trends, the likely outcomes for most AI-in-finance startups are converging around two paths.</p>\n<h4 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"acquisition-by-data-vendors\">Acquisition by data vendors<a href=\"https://didierlopes.com/blog/the-evolution-of-ai-agents-in-finance#acquisition-by-data-vendors\" class=\"hash-link\" aria-label=\"Direct link to Acquisition by data vendors\" title=\"Direct link to Acquisition by data vendors\">​</a></h4>\n<p>They get acquired by big data vendors. Most likely the very same data vendor that is providing the raw data for them to generate derived insights. Not just because these big data vendors want to sell these second-order effect data as another dataset (and we know how much data acquisitions these vendors do, it's literally their playbook for growth), but because:</p>\n<ul>\n<li>They want to bring the expertise of building these agentic experience on top of their data in-house</li>\n<li>As a defense mechanism in case they get acquired by another large vendor that has similar datasets (a good parallel is what happened with Meta's 49% acquisition of ScaleAI and what that meant for OpenAI)</li>\n</ul>\n<p>And honestly, they control the raw inputs, they have the distribution, they have the capital. Not buying the startups that are experimenting on their data would simply be negligence.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"acquisition-by-frontier-ai-labs\">Acquisition by frontier AI labs<a href=\"https://didierlopes.com/blog/the-evolution-of-ai-agents-in-finance#acquisition-by-frontier-ai-labs\" class=\"hash-link\" aria-label=\"Direct link to Acquisition by frontier AI labs\" title=\"Direct link to Acquisition by frontier AI labs\">​</a></h3>\n<p>They get absorbed by the frontier labs. OpenAI, Anthropic, and Google don't need the startup's UI, they want the domain expertise baked into their models.</p>\n<p>A team that has truly cracked bond covenant parsing, or IPO prospectuses becomes far more valuable as part of the foundation model itself. Acquisitions here aren't about market share; they're about hard-won micro domain expertise that can tip the scales in the labs' race for vertical dominance.</p>\n<h4 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"consolidation\">Consolidation<a href=\"https://didierlopes.com/blog/the-evolution-of-ai-agents-in-finance#consolidation\" class=\"hash-link\" aria-label=\"Direct link to Consolidation\" title=\"Direct link to Consolidation\">​</a></h4>\n<p>Either way, consolidation is the destiny of this wave of startups. I don't think that most startups have enough leverage to stand alone once the data vendors and labs have their hooks in.</p>\n<p>The only way I see startups winning big here is by being deeply integrated in large financial firms, but the value cannot be on the data or on the intelligence. It needs to be in something deeper than that, e.g. infrastructure..</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"phase-6-where-does-openbb-fit\">Phase 6: Where does OpenBB fit<a href=\"https://didierlopes.com/blog/the-evolution-of-ai-agents-in-finance#phase-6-where-does-openbb-fit\" class=\"hash-link\" aria-label=\"Direct link to Phase 6: Where does OpenBB fit\" title=\"Direct link to Phase 6: Where does OpenBB fit\">​</a></h2>\n<p>If Phase 5 was about everyone chasing derived insights, <strong>Phase 6 is about financial firms operationalizing those insights on top of their own data.</strong> It's not enough for AI agents to summarize filings or produce signals; the real value comes when firms can combine those machine-generated insights with their proprietary data, and do it securely, on their own terms.</p>\n<p>This is where OpenBB comes in.</p>\n<blockquote>\n<p>The defining feature of Phase 6 is <strong>orchestration of access</strong>: bringing together internal, external, and AI-derived data into one secure, intelligent workspace.</p>\n</blockquote>\n<br>\n<p>The big question facing financial institutions now is simple: do we build our own AI stack from scratch, or do we adopt an open workspace that's already designed for this purpose, and that we can fully own? Incumbent platforms like Bloomberg, FactSet, and Capital IQ were never designed to ingest a client's proprietary data. They have little incentive to let users integrate outside sources, because their business is selling their own datasets. This is the classic <strong>\"Are you team MCP client or MCP server\"</strong> dilemma, I wrote about it <a href=\"https://didierlopes.beehiiv.com/p/are-you-team-mcp-client-or-server\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>. I reckon that most of the big data vendors are team MCP Servers and they want to be the source of data into AI contexts, not the consumer of external data into their walled gardens. They are data businesses at core.</p>\n<p>That's why OpenBB is building the opposite.</p>\n<p>Our vision is an open IDE for finance - an open workspace where a firm can plug in all its data sources (internal databases, vendor feeds, public datasets, even AI-derived insights) and layer on multiple AI models to generate answers, workflows, and ultimately alpha.</p>\n<p>Just as software developers need IDEs, analysts will still need a financial terminal for the foreseeable future. Unfortunately, there wasn't an open source VSCode that we could have used to start building on top, so we built OpenBB Workspace. Relentlessly.</p>\n<p>Critically, Phase 6 also requires <strong>deployment flexibility.</strong> Firms want all of this to run inside their perimeter, on-prem or in a private VPC, so their proprietary edge never leaves their control.</p>\n<p>We designed OpenBB that way from day one.</p>\n<p>The endgame is a <strong>unified intelligence platform for finance</strong>: not just an AI chatbot, but a programmable workspace where human experts and AI agents collaborate over both internal and external data.</p>\n<p>Unlike the vendors, we aren't locked into selling one dataset. Unlike the labs, we aren't just selling raw intelligence. We're building the open infrastructure layer that lets firms put their proprietary edge into intelligence - securely, flexibly, and at scale.</p>\n<p>That's why OpenBB exists. And that's why we have been betting on Phase 6 for so many years.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"conclusion\">Conclusion<a href=\"https://didierlopes.com/blog/the-evolution-of-ai-agents-in-finance#conclusion\" class=\"hash-link\" aria-label=\"Direct link to Conclusion\" title=\"Direct link to Conclusion\">​</a></h2>\n<p>AI agents in finance have come a long way in a very short time, from the early novelty of Q&amp;A on SEC filings, through web-enabled research assistants, to fully integrated multi-source analytics. Yet, as I've argued, there's still another phase on the horizon.</p>\n<p>The real transformation will happen when every financial institution can easily plug its own data into intelligent systems, and do so safely and efficiently. The differentiator won't be the chat interface, it will be the combination of internal and external data with AI, producing a constant stream of new, data-driven insights that firms can actually operationalize.</p>\n<p>OpenBB has been building for this phase for three years. We've designed for private deployments, for open integrations, and for full transparency and control. This isn't a pivot for us, it's the phase we anticipated from the start.</p>\n<p>I believe in this future so strongly that I've made it my life's work. And I'm convinced we're uniquely positioned for it: there simply isn't another product like OpenBB in the market.</p>\n<p>I actually started writing this essay after noticing something in our own client conversations: firms weren't asking to integrate AI-finance startups as agents into our workspace. They were asking to integrate their <strong>outputs</strong> - as input data widgets into our Workspace dashboard. Not different from a sell-side research report on the screen, but this time produced by an agent in 30minutes instead of days. That's the shift. That's Phase 6. That's why we're here, and that's also why we're just getting started.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/the-evolution-of-ai-agents-in-finance",
            "title": "The Evolution of AI Agents in Finance",
            "summary": "Mapping the evolution of AI agents in finance from ChatGPT wrappers to derived data insights - and why the real value is shifting from interfaces to intelligence.",
            "date_modified": "2025-09-23T00:00:00.000Z",
            "tags": [
                "ai",
                "finance",
                "agents",
                "chatgpt",
                "mcp",
                "openbb",
                "fintech",
                "data",
                "anthropic",
                "evolution"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/the-trampoline-job-optimize-your-career-for-growth",
            "content_html": "<p><img decoding=\"async\" loading=\"lazy\" alt=\"The trampoline job - Optimize your career for growth\" src=\"https://didierlopes.com/assets/images/2025-09-19-the-trampoline-job-optimize-your-career-for-growth-05e463b122f692cb2a344536968e06a2.webp\" width=\"541\" height=\"421\" class=\"img_ev3q\"></p>\n<p>Why accepting a lower-paying startup job in San Francisco could be the best career move you ever make - the trampoline effect that launches your trajectory.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>This <a href=\"https://x.com/beaversteever/status/1959972343050068280\" target=\"_blank\" rel=\"noopener noreferrer\">post</a> was trending on X, with critics about the offer.</p>\n<p>If you live in a bubble (SF or NYC) then I understand most of the comments. But I think for the vast majority of the population, this is potentially a life-changing offer.</p>\n<p align=\"center\"><img width=\"500\" src=\"https://didierlopes.com/blog/2025-09-19-the-trampoline-job-optimize-your-career-for-growth_1.webp\" alt=\"Average VC startup offer tweet\"></p>\n<p>So here's story time.</p>\n<p>In 2018, I finished my MSc in Control Systems at Imperial College London, one of the best universities in the world.</p>\n<p>Back then, most \"graduate program\" offers in London were around <strong>£25–27k</strong> per year. That's in one of the most expensive cities in Europe. To make things worse, equity wasn't even part of the conversation; people just didn't talk about it.</p>\n<p>These programs also locked you in for 1–3 years on the same pay band, with the logic that you were \"learning from the real world.\"</p>\n<p>If I'd been offered something different at that point - a role at a small, ambitious startup in San Francisco - I would have taken it in a heartbeat.</p>\n<ul>\n<li>I would have learned far more, far faster.</li>\n<li>I'd be surrounded by like-minded people immersed in tech.</li>\n<li>I'd be part of a company from 0 to 1, seeing how things get built from scratch.</li>\n<li>And I'd likely have saved about the same as in London.</li>\n</ul>\n<p>That's because an early-stage startup offer is not just a job. It's a trampoline.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"why-its-a-trampoline\">Why it's a trampoline<a href=\"https://didierlopes.com/blog/the-trampoline-job-optimize-your-career-for-growth#why-its-a-trampoline\" class=\"hash-link\" aria-label=\"Direct link to Why it's a trampoline\" title=\"Direct link to Why it's a trampoline\">​</a></h2>\n<p>The first few months are tough. You're absorbing everything, getting familiar with the codebase, and figuring out how to contribute real value.</p>\n<p>But soon the leverage kicks in:</p>\n<ul>\n<li>You're shipping faster and adding outsized impact.</li>\n<li>You're meeting people building cool things in adjacent spaces.</li>\n<li>You're doing interviews elsewhere and learning what you're actually worth.</li>\n<li>You're starting to understand how the startup is doing, and what that 0.5% equity stake might mean (spoiler: ignore the \"non-dilution\" mentioned above; that literally never happens).</li>\n</ul>\n<p>Within a year, you've built knowledge, credibility, and a network.</p>\n<p><strong>You now have optionality.</strong></p>\n<p>That's the trampoline effect: the experience bounces you onto a higher trajectory than you could have reached through a traditional grad program.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"most-people-never-get-their-trampoline\">Most people never get their trampoline<a href=\"https://didierlopes.com/blog/the-trampoline-job-optimize-your-career-for-growth#most-people-never-get-their-trampoline\" class=\"hash-link\" aria-label=\"Direct link to Most people never get their trampoline\" title=\"Direct link to Most people never get their trampoline\">​</a></h2>\n<p>Instead, they accept a safe but stagnant 9–5, capped by bureaucracy and slow progression.</p>\n<p><strong>By the time they realize it, the opportunity cost is massive.</strong></p>\n<p>A trampoline job isn't meant to be the forever job, it's the launchpad. If you approach it with intensity, you'll learn faster than anywhere else, build leverage, and set your career on an entirely different trajectory.</p>\n<p>So my recommendation is to optimize early for growth, not comfort.</p>\n<p>Look for trampolines, not treadmills.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/the-trampoline-job-optimize-your-career-for-growth",
            "title": "The trampoline job - Optimize your career for growth",
            "summary": "Why accepting a lower-paying startup job in San Francisco could be the best career move you ever make - the trampoline effect that launches your trajectory.",
            "date_modified": "2025-09-19T00:00:00.000Z",
            "tags": [
                "career",
                "startup",
                "growth",
                "san-francisco",
                "equity",
                "tech",
                "jobs"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/how-i-built-an-mcp-server-for-developers-building-openbb-apps",
            "content_html": "<p>The hardest part of building an OpenBB app isn't writing Python, it's getting the <code>widgets.json</code> spec right, since this spec was invented by us.</p>\n<p>Every app requires developers to define widget types, inputs, and configuration options in exactly the right format. The documentation is strong, but it is long-form, which forces you to dig around for the parts you need. That slows down iteration, especially when you just want to get an idea live in OpenBB Workspace.</p>\n<p>AI feels like a natural solution here. For example, providing the documentation to a model like Claude Code and asking it to generate your <code>widgets.json</code> spec.</p>\n<p>If you ask Claude Code to read the docs from OpenBB, it <strong>kind of works</strong>. But it takes too much time (given the extensive documentation available), wastes a lot of tokens, and the model often gets confused. This is the same as using an MCP server like Context7, except that with Context7 the context is not really guaranteed to be up to date, so it is even worse.</p>\n<p>The alternative is to send the exact part of the page that the model requires, which actually works pretty well. But this is very time consuming for the developer. The problem is that when you are building a complex widget, you need context from a lot of different pages, which increases the risk of not sending the right context and the model hallucinating. So basically, it <strong>doesn't work either</strong>.</p>\n<p>BUT.</p>\n<p>What if, instead of stuffing all the docs into context, <strong>I built an MCP server</strong> where every piece of the documentation is exposed as a structured, callable tool?</p>\n<p align=\"center\"><img width=\"800\" src=\"https://didierlopes.com/blog/2025-09-10-how-i-built-an-mcp-server-for-developers-building-openbb-apps_1.webp\"></p>\n<p>I just had to try it.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"1-breaking-down-the-docs-into-building-blocks\">1. Breaking down the docs into building blocks<a href=\"https://didierlopes.com/blog/how-i-built-an-mcp-server-for-developers-building-openbb-apps#1-breaking-down-the-docs-into-building-blocks\" class=\"hash-link\" aria-label=\"Direct link to 1. Breaking down the docs into building blocks\" title=\"Direct link to 1. Breaking down the docs into building blocks\">​</a></h2>\n<p>I spent the weekend <a href=\"https://github.com/OpenBB-finance/openbb-docs/pull/104\" target=\"_blank\" rel=\"noopener noreferrer\">refactoring OpenBB docs</a> into developer and analyst roles, so I understood very well the principal components that were relevant for developers.</p>\n<p>There are three natural categories of building blocks:</p>\n<ul>\n<li><strong>Widget types</strong>: Plotly charts, AgGrid tables, Markdown, HTML, Metrics, etc.</li>\n<li><strong>Parameters and controls</strong>: dropdowns, toggles, date pickers, text inputs, etc.</li>\n<li><strong>Configuration options</strong>: grid sizing, stale times, error handling, refetch intervals, etc.</li>\n</ul>\n<p>Instead of treating the docs as one big reference, I split them into these <strong>granular tools</strong>.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"2-adding-an-ad-hoc-boilerplate-tool\">2. Adding an ad-hoc boilerplate tool<a href=\"https://didierlopes.com/blog/how-i-built-an-mcp-server-for-developers-building-openbb-apps#2-adding-an-ad-hoc-boilerplate-tool\" class=\"hash-link\" aria-label=\"Direct link to 2. Adding an ad-hoc boilerplate tool\" title=\"Direct link to 2. Adding an ad-hoc boilerplate tool\">​</a></h2>\n<p>On top of the building blocks, I added one special tool: <code>building_widgets_on_openbb</code>.</p>\n<p>This is an <strong>ad-hoc boilerplate reference</strong> that acts as a base. By requiring it to always be called first, I can guarantee that every widget starts from a solid baseline and everything else plugs into that baseline.</p>\n<p>I enforced this behavior with the following MCP tool description:</p>\n<div class=\"language-python codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-python codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token decorator annotation punctuation\" style=\"color:rgb(248, 248, 242)\">@mcp</span><span class=\"token decorator annotation punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token decorator annotation punctuation\" style=\"color:rgb(248, 248, 242)\">tool</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">def</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(80, 250, 123)\">building_widgets_on_openbb</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token plain\"> </span><span class=\"token operator\">-</span><span class=\"token operator\">&gt;</span><span class=\"token plain\"> </span><span class=\"token builtin\" style=\"color:rgb(189, 147, 249)\">str</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    </span><span class=\"token triple-quoted-string string\" style=\"color:rgb(255, 121, 198)\">\"\"\"Essential boilerplate code for building OpenBB Workspace widgets. </span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token triple-quoted-string string\" style=\"color:rgb(255, 121, 198)\">    This provides the foundational FastAPI setup, CORS configuration, widgets.json endpoints, </span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token triple-quoted-string string\" style=\"color:rgb(255, 121, 198)\">    and register_widget decorator pattern. ALWAYS call this first when creating OpenBB widgets </span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token triple-quoted-string string\" style=\"color:rgb(255, 121, 198)\">    to get the required boilerplate structure.\"\"\"</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    </span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    </span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">return</span><span class=\"token plain\"> </span><span class=\"token triple-quoted-string string\" style=\"color:rgb(255, 121, 198)\">\"\"\"# Essential Boilerplate Code for OpenBB Workspace Widgets</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token triple-quoted-string string\" style=\"color:rgb(255, 121, 198)\">...</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token triple-quoted-string string\" style=\"color:rgb(255, 121, 198)\">\"\"\"</span><br></span></code></pre></div></div>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"3-using-fastmcp-to-turn-everything-into-tools\">3. Using FastMCP to turn everything into tools<a href=\"https://didierlopes.com/blog/how-i-built-an-mcp-server-for-developers-building-openbb-apps#3-using-fastmcp-to-turn-everything-into-tools\" class=\"hash-link\" aria-label=\"Direct link to 3. Using FastMCP to turn everything into tools\" title=\"Direct link to 3. Using FastMCP to turn everything into tools\">​</a></h2>\n<p>I used <strong>FastMCP</strong> to create a tool for each block. Every widget type, parameter, and configuration setting is its own MCP endpoint.</p>\n<p>So instead of asking the AI, \"What's the JSON spec for a dropdown?\" and hoping it parses the docs correctly, the AI can just call:</p>\n<ul>\n<li><code>widget_parameters_dropdown</code></li>\n<li><code>widget_types_plotly_charts</code></li>\n<li><code>widget_configuration_grid_size</code></li>\n</ul>\n<p>and immediately get valid JSON to work with.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"4-deploying-on-smitheryai-for-easy-access\">4. Deploying on Smithery.ai for easy access<a href=\"https://didierlopes.com/blog/how-i-built-an-mcp-server-for-developers-building-openbb-apps#4-deploying-on-smitheryai-for-easy-access\" class=\"hash-link\" aria-label=\"Direct link to 4. Deploying on Smithery.ai for easy access\" title=\"Direct link to 4. Deploying on Smithery.ai for easy access\">​</a></h2>\n<p>Finally, I deployed the server on Smithery.ai. That makes it discoverable, shareable, and instantly usable, with no local setup required. You can connect Claude Desktop, Cursor, or Smithery Playground to it in seconds.</p>\n<p>It became immediately available <a href=\"https://smithery.ai/server/@DidierRLopes/openbb-docs-mcp\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<p align=\"center\"><img width=\"800\" src=\"https://didierlopes.com/blog/2025-09-10-how-i-built-an-mcp-server-for-developers-building-openbb-apps.webp\"></p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"5-testing\">5. Testing<a href=\"https://didierlopes.com/blog/how-i-built-an-mcp-server-for-developers-building-openbb-apps#5-testing\" class=\"hash-link\" aria-label=\"Direct link to 5. Testing\" title=\"Direct link to 5. Testing\">​</a></h2>\n<p>But I didn't just deploy and hope for the best.</p>\n<p>Instead, I clicked on \"Explore capabilities\" on the <a href=\"https://smithery.ai/server/@DidierRLopes/openbb-docs-mcp\" target=\"_blank\" rel=\"noopener noreferrer\">smithery.ai page</a> and asked it to create a complicated <code>widgets.json</code> spec for a specific widget request.</p>\n<p>It didn't work perfectly at first.</p>\n<p>But that's okay. I went back and improved the docs (and even realized that I needed the ad-hoc boilerplate tool).</p>\n<p>Eventually, it worked.</p>\n<p align=\"center\"><img width=\"800\" src=\"https://didierlopes.com/blog/2025-09-10-how-i-built-an-mcp-server-for-developers-building-openbb-apps_2.webp\"></p>\n<p align=\"center\"><img width=\"800\" src=\"https://didierlopes.com/blog/2025-09-10-how-i-built-an-mcp-server-for-developers-building-openbb-apps_3.webp\"></p>\n<p align=\"center\"><img width=\"800\" src=\"https://didierlopes.com/blog/2025-09-10-how-i-built-an-mcp-server-for-developers-building-openbb-apps_4.webp\"></p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"how-to-use-it\">How to use it<a href=\"https://didierlopes.com/blog/how-i-built-an-mcp-server-for-developers-building-openbb-apps#how-to-use-it\" class=\"hash-link\" aria-label=\"Direct link to How to use it\" title=\"Direct link to How to use it\">​</a></h2>\n<p>Here's how you may use this OpenBB widgets.json spec MCP Server with Claude Code.</p>\n<ol>\n<li>Add this MCP Server to Claude Code (URL <a href=\"https://server.smithery.ai/@DidierRLopes/openbb-docs-mcp/mcp\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>)</li>\n</ol>\n<div class=\"language-bash codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-bash codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">claude mcp add --transport http openbb-docs-mcp https://server.smithery.ai/@DidierRLopes/openbb-docs-mcp/mcp</span><br></span></code></pre></div></div>\n<ol start=\"2\">\n<li>Set up MCP Server and authenticate</li>\n</ol>\n<p>And ensure you see a \"✅ connected\"</p>\n<p align=\"center\"><img width=\"800\" src=\"https://didierlopes.com/blog/2025-09-10-how-i-built-an-mcp-server-for-developers-building-openbb-apps_5.webp\"></p>\n<ol start=\"3\">\n<li>Then ask your prompt, and you need to confirm that CC can access these MCP tools.</li>\n</ol>\n<p>This is what you expect to see:</p>\n<p align=\"center\"><img width=\"800\" src=\"https://didierlopes.com/blog/2025-09-10-how-i-built-an-mcp-server-for-developers-building-openbb-apps_6.webp\"></p>\n<p>In the end, you should be able to get the correct <code>widgets.json</code> spec.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"monte-carlo-stock-simulation-widget\">Monte Carlo stock simulation widget<a href=\"https://didierlopes.com/blog/how-i-built-an-mcp-server-for-developers-building-openbb-apps#monte-carlo-stock-simulation-widget\" class=\"hash-link\" aria-label=\"Direct link to Monte Carlo stock simulation widget\" title=\"Direct link to Monte Carlo stock simulation widget\">​</a></h2>\n<p>In order to test this, I ask CC:</p>\n<p><em>Create an OpenBB widget that has 3 parameters (ticker str, start date and boolean). The data is meant to be a plotly chart, but also support raw data. And because it's a monte carlo simulation, can you add a run button to it?</em></p>\n<p>But essentially, it allowed me to connect this one-shot widget to the workspace:</p>\n<p align=\"center\"><img width=\"800\" src=\"https://didierlopes.com/blog/2025-09-10-how-i-built-an-mcp-server-for-developers-building-openbb-apps_7.webp\"></p>\n<p>Note the difficulty associated with building this widget from scratch:</p>\n<ul>\n<li>Requires adding the boilerplate code</li>\n<li>Requires a Plotly visualization with simulation paths plus percentile bands</li>\n<li>Adds 3 parameters: <code>ticker</code> (text), <code>start_date</code> (date), <code>use_volatility_adjustment</code> (boolean)</li>\n<li>Raw data mode returning pure simulation arrays</li>\n<li>A run button for manual execution</li>\n</ul>\n<p>This example shows the end-to-end workflow:</p>\n<p><strong>AI + MCP server → OpenBB widget in minutes.</strong></p>\n<p>One recommendation I have is to separate the data problem from the <code>widgets.json</code> specs. Make sure it works with mock data first, and once that is figured out, you just need to ensure you can push the correct data to it.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"tldr\">tl;dr<a href=\"https://didierlopes.com/blog/how-i-built-an-mcp-server-for-developers-building-openbb-apps#tldr\" class=\"hash-link\" aria-label=\"Direct link to tl;dr\" title=\"Direct link to tl;dr\">​</a></h2>\n<p>AI as a search engine for docs is messy and inconsistent.</p>\n<p><strong>AI as a programmable assistant with tools is structured, accurate, and composable.</strong></p>\n<p>By exposing the docs as tools, you reduce hallucinations, improve accuracy, and make it much easier for developers to mix and match widget components when building new OpenBB apps.</p>\n<p>Happy hacking!</p>\n<p><strong>PS:</strong> We are actually working on introducing Widget Studio, which will greatly simplify the user experience of building custom widgets in the workspace, particularly when it comes to the UI.</p>\n<p align=\"center\"><img width=\"800\" src=\"https://didierlopes.com/blog/2025-09-10-how-i-built-an-mcp-server-for-developers-building-openbb-apps_8.webp\"></p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/how-i-built-an-mcp-server-for-developers-building-openbb-apps",
            "title": "How I built an MCP Server for developers building OpenBB apps",
            "summary": "The hardest part of building an OpenBB app isn't writing Python, it's getting the widgets.json spec right. I built an MCP server to expose every piece of documentation as a structured, callable tool.",
            "date_modified": "2025-09-10T00:00:00.000Z",
            "tags": [
                "openbb",
                "mcp",
                "ai",
                "development",
                "tools",
                "documentation"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/tracking-your-partner-health-stats-with-oura-and-ai",
            "content_html": "<p>The rise of health tracking devices has given us unprecedented insight into our daily wellness metrics. But what if you could use that data not just for personal optimization, but for relationship optimization?</p>\n<p>I was scrolling through X the other day while waiting for Claude Code to finish running something else, and I saw a post about someone using the Oura API.</p>\n<p>My wife absolutely loves her Oura ring and all the metrics it provides her. The same way it gives her these insights, I realized I could have access to them too.</p>\n<p>But what if on top of the metrics I had AI giving me tactical advice on how to navigate married life? Picture this:</p>\n<ul>\n<li>She's slept poorly, so she'll be grumpy - tactical retreat recommended</li>\n<li>She's well-rested and in a good mood - perfect time to ask for that roast dinner</li>\n</ul>\n<p>So on Sunday morning, I decided to quickly build something fun.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"ios-widget\">iOS widget<a href=\"https://didierlopes.com/blog/tracking-your-partner-health-stats-with-oura-and-ai#ios-widget\" class=\"hash-link\" aria-label=\"Direct link to iOS widget\" title=\"Direct link to iOS widget\">​</a></h2>\n<p>I built a Scriptable iOS widget that displays my wife's health metrics in an RPG-style interface with AI-generated British humor.</p>\n<p align=\"center\"><img width=\"800\" src=\"https://didierlopes.com/blog/2025-09-06-tracking-your-partner-health-stats-with-oura-and-ai.webp\"></p>\n<p><strong>Key features:</strong></p>\n<ul>\n<li>RPG-style HP hearts showing her readiness level (❤️❤️❤️🖤🖤)</li>\n<li>Activity and Sleep score displayed on the bottom left and right corners, respectively</li>\n<li>AI-generated British humor management tips. Context includes:<!-- -->\n<ul>\n<li>Readiness score, activity score (and steps), sleep score (and hours slept)</li>\n<li>The health data from yesterday to be used as a reference from shifts</li>\n<li>Current datetime as recommendation will differ from the time of the day</li>\n<li>Guidelines on the type of sentence to write</li>\n<li>Examples of sentences - for few shot prompting</li>\n</ul>\n</li>\n</ul>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"step-by-step-technical-implementation\">Step-by-step technical implementation<a href=\"https://didierlopes.com/blog/tracking-your-partner-health-stats-with-oura-and-ai#step-by-step-technical-implementation\" class=\"hash-link\" aria-label=\"Direct link to Step-by-step technical implementation\" title=\"Direct link to Step-by-step technical implementation\">​</a></h2>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"setting-up-the-foundation\">Setting up the foundation<a href=\"https://didierlopes.com/blog/tracking-your-partner-health-stats-with-oura-and-ai#setting-up-the-foundation\" class=\"hash-link\" aria-label=\"Direct link to Setting up the foundation\" title=\"Direct link to Setting up the foundation\">​</a></h3>\n<p><strong>Challenge</strong>: Creating a widget that could access external APIs and display dynamic content on iOS.</p>\n<p><strong>Solution</strong>: Used Scriptable app as the platform, which allows JavaScript execution with native iOS widget capabilities. → easy for me to access.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"oura-api-integration\">Oura API integration<a href=\"https://didierlopes.com/blog/tracking-your-partner-health-stats-with-oura-and-ai#oura-api-integration\" class=\"hash-link\" aria-label=\"Direct link to Oura API integration\" title=\"Direct link to Oura API integration\">​</a></h3>\n<p>I connected to Oura Cloud API v2 endpoints and fetched multiple data streams: <em>daily_readiness</em>, <em>daily_sleep</em>, <em>sleep</em> sessions, and <em>daily_activity</em>. Built robust error handling for API failures and handled data from multiple days for comparison metrics.</p>\n<div class=\"language-javascript codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-javascript codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">const</span><span class=\"token plain\"> headers </span><span class=\"token operator\">=</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">{</span><span class=\"token plain\"> </span><span class=\"token string-property property\">\"Authorization\"</span><span class=\"token operator\">:</span><span class=\"token plain\"> </span><span class=\"token template-string template-punctuation string\" style=\"color:rgb(255, 121, 198)\">`</span><span class=\"token template-string string\" style=\"color:rgb(255, 121, 198)\">Bearer </span><span class=\"token template-string interpolation interpolation-punctuation punctuation\" style=\"color:rgb(248, 248, 242)\">${</span><span class=\"token template-string interpolation constant\" style=\"color:rgb(189, 147, 249)\">OURA_TOKEN</span><span class=\"token template-string interpolation interpolation-punctuation punctuation\" style=\"color:rgb(248, 248, 242)\">}</span><span class=\"token template-string template-punctuation string\" style=\"color:rgb(255, 121, 198)\">`</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">}</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">const</span><span class=\"token plain\"> readinessUrl </span><span class=\"token operator\">=</span><span class=\"token plain\"> </span><span class=\"token template-string template-punctuation string\" style=\"color:rgb(255, 121, 198)\">`</span><span class=\"token template-string string\" style=\"color:rgb(255, 121, 198)\">https://api.ouraring.com/v2/usercollection/daily_readiness?start_date=</span><span class=\"token template-string interpolation interpolation-punctuation punctuation\" style=\"color:rgb(248, 248, 242)\">${</span><span class=\"token template-string interpolation\">yesterday</span><span class=\"token template-string interpolation interpolation-punctuation punctuation\" style=\"color:rgb(248, 248, 242)\">}</span><span class=\"token template-string string\" style=\"color:rgb(255, 121, 198)\">&amp;end_date=</span><span class=\"token template-string interpolation interpolation-punctuation punctuation\" style=\"color:rgb(248, 248, 242)\">${</span><span class=\"token template-string interpolation\">today</span><span class=\"token template-string interpolation interpolation-punctuation punctuation\" style=\"color:rgb(248, 248, 242)\">}</span><span class=\"token template-string template-punctuation string\" style=\"color:rgb(255, 121, 198)\">`</span><br></span></code></pre></div></div>\n<p>This was all done with Claude Code in a few minutes.</p>\n<p>Before I even touched on Scriptable, I made sure that with Meg's Oura PAT (personal access token) I could access the data.</p>\n<p>I did so by asking Claude Code to check if it could retrieve that data, and so it one-shot a few scripts to test the API and it worked perfectly.</p>\n<p>Previously this used to take a bit of time because you had to read the documentation, etc - but now CC can just iterate with you quickly.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"ai-powered-contextual-advice\">AI-powered contextual advice<a href=\"https://didierlopes.com/blog/tracking-your-partner-health-stats-with-oura-and-ai#ai-powered-contextual-advice\" class=\"hash-link\" aria-label=\"Direct link to AI-powered contextual advice\" title=\"Direct link to AI-powered contextual advice\">​</a></h3>\n<p>This isn't just displaying numbers - it creates a funny sentence on what to do! I integrated OpenAI's model to get contextual advice based on my wife's raw biometric data.</p>\n<p>Rather than just showing generic health scores, the AI actually thinks about the full picture. A 60% readiness score at 7 AM when she's been sleeping poorly hits way different than the same score at 9 PM after she got a good night's rest. Context matters.</p>\n<p><strong>My prompt:</strong></p>\n<p>This is arguably the part that took me the longest - maybe 20 minutes or so.</p>\n<div class=\"language-javascript codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-javascript codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">const</span><span class=\"token plain\"> prompt </span><span class=\"token operator\">=</span><span class=\"token plain\"> </span><span class=\"token template-string template-punctuation string\" style=\"color:rgb(255, 121, 198)\">`</span><span class=\"token template-string string\" style=\"color:rgb(255, 121, 198)\">You are a cheeky British AI assistant helping a husband manage his wife Meg. Generate a funny, dramatic 1-2 sentence management advisory based on her biometric data:</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token template-string string\" style=\"display:inline-block;color:rgb(255, 121, 198)\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token template-string string\" style=\"color:rgb(255, 121, 198)\">Today metrics:</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token template-string string\" style=\"color:rgb(255, 121, 198)\">- Energy Level: </span><span class=\"token template-string interpolation interpolation-punctuation punctuation\" style=\"color:rgb(248, 248, 242)\">${</span><span class=\"token template-string interpolation\">ouraData</span><span class=\"token template-string interpolation punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token template-string interpolation property-access\">readiness</span><span class=\"token template-string interpolation interpolation-punctuation punctuation\" style=\"color:rgb(248, 248, 242)\">}</span><span class=\"token template-string string\" style=\"color:rgb(255, 121, 198)\">/100</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token template-string string\" style=\"color:rgb(255, 121, 198)\">- Sleep Quality: </span><span class=\"token template-string interpolation interpolation-punctuation punctuation\" style=\"color:rgb(248, 248, 242)\">${</span><span class=\"token template-string interpolation\">ouraData</span><span class=\"token template-string interpolation punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token template-string interpolation property-access\">sleep</span><span class=\"token template-string interpolation interpolation-punctuation punctuation\" style=\"color:rgb(248, 248, 242)\">}</span><span class=\"token template-string string\" style=\"color:rgb(255, 121, 198)\">/100  </span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token template-string string\" style=\"color:rgb(255, 121, 198)\">- Activity Performance: </span><span class=\"token template-string interpolation interpolation-punctuation punctuation\" style=\"color:rgb(248, 248, 242)\">${</span><span class=\"token template-string interpolation\">ouraData</span><span class=\"token template-string interpolation punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token template-string interpolation property-access\">activity</span><span class=\"token template-string interpolation interpolation-punctuation punctuation\" style=\"color:rgb(248, 248, 242)\">}</span><span class=\"token template-string string\" style=\"color:rgb(255, 121, 198)\">/100</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token template-string string\" style=\"color:rgb(255, 121, 198)\">- Sleep Duration: </span><span class=\"token template-string interpolation interpolation-punctuation punctuation\" style=\"color:rgb(248, 248, 242)\">${</span><span class=\"token template-string interpolation\">ouraData</span><span class=\"token template-string interpolation punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token template-string interpolation property-access\">sleepDuration</span><span class=\"token template-string interpolation punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token template-string interpolation method function property-access\" style=\"color:rgb(80, 250, 123)\">toFixed</span><span class=\"token template-string interpolation punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token template-string interpolation number\">1</span><span class=\"token template-string interpolation punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token template-string interpolation interpolation-punctuation punctuation\" style=\"color:rgb(248, 248, 242)\">}</span><span class=\"token template-string string\" style=\"color:rgb(255, 121, 198)\"> hours</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token template-string string\" style=\"color:rgb(255, 121, 198)\">- Steps Taken: </span><span class=\"token template-string interpolation interpolation-punctuation punctuation\" style=\"color:rgb(248, 248, 242)\">${</span><span class=\"token template-string interpolation\">ouraData</span><span class=\"token template-string interpolation punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token template-string interpolation property-access\">steps</span><span class=\"token template-string interpolation interpolation-punctuation punctuation\" style=\"color:rgb(248, 248, 242)\">}</span><span class=\"token template-string string\" style=\"color:rgb(255, 121, 198)\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token template-string string\" style=\"color:rgb(255, 121, 198)\">- Current Time: </span><span class=\"token template-string interpolation interpolation-punctuation punctuation\" style=\"color:rgb(248, 248, 242)\">${</span><span class=\"token template-string interpolation\">timeOfDay</span><span class=\"token template-string interpolation interpolation-punctuation punctuation\" style=\"color:rgb(248, 248, 242)\">}</span><span class=\"token template-string string\" style=\"color:rgb(255, 121, 198)\"> (</span><span class=\"token template-string interpolation interpolation-punctuation punctuation\" style=\"color:rgb(248, 248, 242)\">${</span><span class=\"token template-string interpolation\">hour</span><span class=\"token template-string interpolation interpolation-punctuation punctuation\" style=\"color:rgb(248, 248, 242)\">}</span><span class=\"token template-string string\" style=\"color:rgb(255, 121, 198)\">:</span><span class=\"token template-string interpolation interpolation-punctuation punctuation\" style=\"color:rgb(248, 248, 242)\">${</span><span class=\"token template-string interpolation\">now</span><span class=\"token template-string interpolation punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token template-string interpolation method function property-access\" style=\"color:rgb(80, 250, 123)\">getMinutes</span><span class=\"token template-string interpolation punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token template-string interpolation punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token template-string interpolation punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token template-string interpolation method function property-access\" style=\"color:rgb(80, 250, 123)\">toString</span><span class=\"token template-string interpolation punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token template-string interpolation punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token template-string interpolation punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token template-string interpolation method function property-access\" style=\"color:rgb(80, 250, 123)\">padStart</span><span class=\"token template-string interpolation punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token template-string interpolation number\">2</span><span class=\"token template-string interpolation punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token template-string interpolation\"> </span><span class=\"token template-string interpolation string\" style=\"color:rgb(255, 121, 198)\">'0'</span><span class=\"token template-string interpolation punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token template-string interpolation interpolation-punctuation punctuation\" style=\"color:rgb(248, 248, 242)\">}</span><span class=\"token template-string string\" style=\"color:rgb(255, 121, 198)\">)</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token template-string string\" style=\"display:inline-block;color:rgb(255, 121, 198)\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token template-string string\" style=\"color:rgb(255, 121, 198)\">Yesterday metrics:</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token template-string string\" style=\"color:rgb(255, 121, 198)\">- Activity: </span><span class=\"token template-string interpolation interpolation-punctuation punctuation\" style=\"color:rgb(248, 248, 242)\">${</span><span class=\"token template-string interpolation\">ouraData</span><span class=\"token template-string interpolation punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token template-string interpolation property-access\">yesterdayActivity</span><span class=\"token template-string interpolation interpolation-punctuation punctuation\" style=\"color:rgb(248, 248, 242)\">}</span><span class=\"token template-string string\" style=\"color:rgb(255, 121, 198)\">/100</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token template-string string\" style=\"color:rgb(255, 121, 198)\">- Steps: </span><span class=\"token template-string interpolation interpolation-punctuation punctuation\" style=\"color:rgb(248, 248, 242)\">${</span><span class=\"token template-string interpolation\">ouraData</span><span class=\"token template-string interpolation punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token template-string interpolation property-access\">yesterdaySteps</span><span class=\"token template-string interpolation interpolation-punctuation punctuation\" style=\"color:rgb(248, 248, 242)\">}</span><span class=\"token template-string string\" style=\"color:rgb(255, 121, 198)\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token template-string string\" style=\"color:rgb(255, 121, 198)\">- Sleep Quality: </span><span class=\"token template-string interpolation interpolation-punctuation punctuation\" style=\"color:rgb(248, 248, 242)\">${</span><span class=\"token template-string interpolation\">ouraData</span><span class=\"token template-string interpolation punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token template-string interpolation property-access\">yesterdaySleep</span><span class=\"token template-string interpolation\"> </span><span class=\"token template-string interpolation operator\">||</span><span class=\"token template-string interpolation\"> </span><span class=\"token template-string interpolation number\">0</span><span class=\"token template-string interpolation interpolation-punctuation punctuation\" style=\"color:rgb(248, 248, 242)\">}</span><span class=\"token template-string string\" style=\"color:rgb(255, 121, 198)\">/100 vs today's </span><span class=\"token template-string interpolation interpolation-punctuation punctuation\" style=\"color:rgb(248, 248, 242)\">${</span><span class=\"token template-string interpolation\">ouraData</span><span class=\"token template-string interpolation punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token template-string interpolation property-access\">sleep</span><span class=\"token template-string interpolation interpolation-punctuation punctuation\" style=\"color:rgb(248, 248, 242)\">}</span><span class=\"token template-string string\" style=\"color:rgb(255, 121, 198)\">/100</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token template-string string\" style=\"color:rgb(255, 121, 198)\">- Sleep Duration: </span><span class=\"token template-string interpolation interpolation-punctuation punctuation\" style=\"color:rgb(248, 248, 242)\">${</span><span class=\"token template-string interpolation punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token template-string interpolation\">ouraData</span><span class=\"token template-string interpolation punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token template-string interpolation property-access\">yesterdaySleepDuration</span><span class=\"token template-string interpolation\"> </span><span class=\"token template-string interpolation operator\">||</span><span class=\"token template-string interpolation\"> </span><span class=\"token template-string interpolation number\">0</span><span class=\"token template-string interpolation punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token template-string interpolation punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token template-string interpolation method function property-access\" style=\"color:rgb(80, 250, 123)\">toFixed</span><span class=\"token template-string interpolation punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token template-string interpolation number\">1</span><span class=\"token template-string interpolation punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token template-string interpolation interpolation-punctuation punctuation\" style=\"color:rgb(248, 248, 242)\">}</span><span class=\"token template-string string\" style=\"color:rgb(255, 121, 198)\">h vs today's </span><span class=\"token template-string interpolation interpolation-punctuation punctuation\" style=\"color:rgb(248, 248, 242)\">${</span><span class=\"token template-string interpolation\">ouraData</span><span class=\"token template-string interpolation punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token template-string interpolation property-access\">sleepDuration</span><span class=\"token template-string interpolation punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token template-string interpolation method function property-access\" style=\"color:rgb(80, 250, 123)\">toFixed</span><span class=\"token template-string interpolation punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token template-string interpolation number\">1</span><span class=\"token template-string interpolation punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token template-string interpolation interpolation-punctuation punctuation\" style=\"color:rgb(248, 248, 242)\">}</span><span class=\"token template-string string\" style=\"color:rgb(255, 121, 198)\">h</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token template-string string\" style=\"display:inline-block;color:rgb(255, 121, 198)\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token template-string string\" style=\"color:rgb(255, 121, 198)\">MANAGEMENT GUIDELINES:</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token template-string string\" style=\"color:rgb(255, 121, 198)\">- High metrics = confident wife, low maintenance mode</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token template-string string\" style=\"color:rgb(255, 121, 198)\">- Low metrics = deploy emergency protocols (tea, snacks, Netflix)</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token template-string string\" style=\"color:rgb(255, 121, 198)\">- Use British expressions: jammy, brilliant, proper, chuffed, knackered, blimey, crikey, ace, smashing</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token template-string string\" style=\"color:rgb(255, 121, 198)\">- Reference UK treats: tea, hobnobs, digestives, biscuits, Yorkshire tea, crumpets, chippy</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token template-string string\" style=\"color:rgb(255, 121, 198)\">- Time-based recommendations: morning=brew up, afternoon=snack deployment, evening=telly time</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token template-string string\" style=\"color:rgb(255, 121, 198)\">- Include tactical advice for optimal wife management</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token template-string string\" style=\"color:rgb(255, 121, 198)\">- Keep it cheeky, affectionate, and dramatically helpful</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token template-string string\" style=\"color:rgb(255, 121, 198)\">- No emojis in response</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token template-string string\" style=\"display:inline-block;color:rgb(255, 121, 198)\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token template-string string\" style=\"color:rgb(255, 121, 198)\">Examples:</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token template-string string\" style=\"color:rgb(255, 121, 198)\">- \"Wife operating at peak performance - minimal intervention required, perhaps celebratory hobnobs\"</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token template-string string\" style=\"color:rgb(255, 121, 198)\">- \"Danger zone detected: Deploy emergency tea protocol and activate Netflix immediately\"</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token template-string string\" style=\"color:rgb(255, 121, 198)\">- \"Meg's running on fumes - tactical retreat advised, arm yourself with digestives\"</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token template-string string\" style=\"color:rgb(255, 121, 198)\">- \"Queen is properly chuffed today - excellent time for difficult conversations\"</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token template-string string\" style=\"color:rgb(255, 121, 198)\">- \"Low battery mode activated - approach with Yorkshire tea and zero expectations\"</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token template-string string\" style=\"display:inline-block;color:rgb(255, 121, 198)\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token template-string string\" style=\"color:rgb(255, 121, 198)\">Output a single sentence (with 1 to 2 phrases). Do not add any \"-\" or quotes.</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token template-string string\" style=\"color:rgb(255, 121, 198)\">You are providing this recommendation to the husband.</span><span class=\"token template-string template-punctuation string\" style=\"color:rgb(255, 121, 198)\">`</span><br></span></code></pre></div></div>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"rpg-style-ui-design\">RPG-Style UI Design<a href=\"https://didierlopes.com/blog/tracking-your-partner-health-stats-with-oura-and-ai#rpg-style-ui-design\" class=\"hash-link\" aria-label=\"Direct link to RPG-Style UI Design\" title=\"Direct link to RPG-Style UI Design\">​</a></h3>\n<p>I wanted to make this actually fun to look at, so here's the styling that I went for:</p>\n<ul>\n<li><strong>Top:</strong> Wife's name + HP hearts (instant status check)</li>\n<li><strong>Middle:</strong> AI tactical advice (the good stuff)</li>\n<li><strong>Bottom:</strong> Raw stats for context (Activity: 85%, Sleep: 92%)</li>\n</ul>\n<p>I went with soft pink to blue gradients because my wife likes those colors, and then I can send her a screenshot of her mood.</p>\n<p>Here's how it looks in practice:</p>\n<p align=\"center\"><img width=\"400\" src=\"https://didierlopes.com/blog/2025-09-06-tracking-your-partner-health-stats-with-oura-and-ai_1.webp\"></p>\n<p>And you can see that I acted immediately on the recommendation by bringing a coffee and hobnobs 😄</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"implement-it-yourself\">Implement it yourself<a href=\"https://didierlopes.com/blog/tracking-your-partner-health-stats-with-oura-and-ai#implement-it-yourself\" class=\"hash-link\" aria-label=\"Direct link to Implement it yourself\" title=\"Direct link to Implement it yourself\">​</a></h2>\n<p>I'm sharing the complete code so you can recreate this for yourself. The full implementation including all the API integration, caching logic, AI prompting, and UI design.</p>\n<p>You'll just need:</p>\n<ol>\n<li>An Oura API token (from your partner's account, with permission!)</li>\n<li>An OpenAI API key</li>\n<li>The Scriptable app on iOS</li>\n</ol>\n<p>Feel free to customize the AI personality, adjust the health metrics display, or modify the caching intervals to suit your needs.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"other-thoughts\">Other thoughts<a href=\"https://didierlopes.com/blog/tracking-your-partner-health-stats-with-oura-and-ai#other-thoughts\" class=\"hash-link\" aria-label=\"Direct link to Other thoughts\" title=\"Direct link to Other thoughts\">​</a></h2>\n<p>Imagine the alpha potential in tracking health stats of executives at public companies:</p>\n<ul>\n<li>CEO sleep patterns before earnings calls</li>\n<li>Recovery metrics during crisis periods</li>\n<li>Team health dynamics during product launches</li>\n</ul>\n<p>If you knew that a company's leadership team was consistently sleep-deprived, highly stressed, and showing declining health metrics leading up to a major product launch, wouldn't that inform your investment decisions?</p>\n<p>We might be heading toward a world where VCs require portfolio company founders to wear Oura rings. Imagine the due diligence: \"<em>Your burn rate looks good, your team is solid, but your founder's recovery score has been below 60% for three months straight. That's a red flag.</em>\"</p>\n<p>Another thought is that Oura is potentially sitting on a gold mine? The patterns in sleep, stress, and recovery among successful entrepreneurs, executives, and decision-makers could be worth more than the hardware business itself.</p>\n<p>Imagine how much HFs would pay to get access to these health stats from high-level execs at companies under their mandate.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/tracking-your-partner-health-stats-with-oura-and-ai",
            "title": "Tracking your partner's health stats with Oura and AI",
            "summary": "The rise of health tracking devices has given us unprecedented insight into our daily wellness metrics. But what if you could use that data not just for personal optimization, but for relationship optimization?",
            "date_modified": "2025-09-06T00:00:00.000Z",
            "tags": [
                "health",
                "ai",
                "relationships",
                "ios",
                "api",
                "humor"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/fine-tuning-a-llm-on-my-blog-posts",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-09-02-fine-tuning-a-llm-on-my-blog-posts.webp\"></p>\n<p>Ever wondered what it would be like to have an AI that writes exactly in your style? I did. And in this post, I share what I did about it. This is a very practical guide on how to fine-tune an LLM using LoRA with MLX on Apple Silicon.</p>\n<!-- -->\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>At the start of the year I shared <a href=\"https://didierlopes.com/blog/turn-my-blog-feed-into-a-qa-dataset-to-fine-tune-a-llm\" target=\"_blank\" rel=\"noopener noreferrer\">this blogpost</a>, which converted all my blogs into a Q&amp;A dataset that I could use to fine-tune a LLM.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-09-02-fine-tuning-a-llm-on-my-blog-posts_1.webp\"></p>\n<p>After sharing this, I spent time trying to fine-tune an LLM - but results were not great and combined with all things happening at OpenBB I didn't have time to dedicate a lot of time to this. <!-- -->:upside-down-hf-logo</p>\n<p>But I hate leaving things half way. And this task didn’t leave my TODO for the past 6 months.</p>\n<p>So I finally took things to my hands last weekend, and I’m going to share the entire journey on what, why and how.</p>\n<p>Buckle up, this will be a long post - and more technical than previous ones. And all the code will be available here: <a href=\"https://github.com/DidierRLopes/fine-tune-llm\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/DidierRLopes/fine-tune-llm</a>.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"context\">Context<a href=\"https://didierlopes.com/blog/fine-tuning-a-llm-on-my-blog-posts#context\" class=\"hash-link\" aria-label=\"Direct link to Context\" title=\"Direct link to Context\">​</a></h2>\n<p>Most AI models are like Wikipedia - they know a little about everything but lack the depth and personality that comes from lived experience.</p>\n<p>Think of it this way: RAG is like giving someone a reference book during an exam. Fine-tuning is like actually teaching them the subject until it becomes part of how they think.</p>\n<blockquote>\n<p><em>“Once you’ve maximized the performance gains from prompting, you might wonder whether to do RAG or finetuning next. The answer depends on whether your model’s failures are information-based or behavior-based.</em></p>\n<p><em>If the model fails because it lacks information, a RAG syustem that gives the model access to the relevant sources of information can help. (…) On the other hand, if the model has behavioral issues, finetuning might help.”</em></p>\n<br>\n<p>- Chip Huyen’s - AI Engineering (Chapter 7: Finetuning)</p>\n</blockquote>\n<br>\n<p>When you fine-tune a model on your writing, you're not just feeding it information (particularly with small models and a LoRA - you're rewiring how it processes and responds to ideas. The same neural pathways that learned to write about quantum physics now learn your specific way of sharing thoughts on open source, MCP, boxing, and others.</p>\n<p>In this case, because we will fine-tune an instruct model - even the system prompt becomes part of this personalization process from the very first token. It’s not a simple “You are a helpful assistant\" but “You are Didier, CEO of OpenBB. You write with clarity and impact, focusing on fintech, open source, AI, and the future of research workflows”.</p>\n<p>This will result in a fine-tuned model that thinks in your voice and operates with your expertise baseline. To some extent that is, we will see later that the information transfer could be better. I attribute that to the fact that we are using a small (3.8B model), we are doing partial fine-tuning (only 0.08% of weights will be updated) and I didn’t spend a lot of time iterating on the hyperparameters.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"0-setting-up-the-foundation\">0. Setting up the foundation<a href=\"https://didierlopes.com/blog/fine-tuning-a-llm-on-my-blog-posts#0-setting-up-the-foundation\" class=\"hash-link\" aria-label=\"Direct link to 0. Setting up the foundation\" title=\"Direct link to 0. Setting up the foundation\">​</a></h2>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"model\">Model<a href=\"https://didierlopes.com/blog/fine-tuning-a-llm-on-my-blog-posts#model\" class=\"hash-link\" aria-label=\"Direct link to Model\" title=\"Direct link to Model\">​</a></h3>\n<p>I chose <strong>Microsoft's Phi-3 mini model (3.8B parameters)</strong> for several strategic reasons beyond just \"it fits on my Mac\":</p>\n<p><strong>Technical sweet spot</strong>: At 3.8B parameters, Phi-3 mini hits the perfect balance - large enough to produce coherent, contextual responses, but small enough to fine-tune efficiently on consumer hardware. Larger models like 7B+ would require more aggressive quantization.</p>\n<p><strong>Instruct-optimized foundation</strong>: This isn't a raw base model. Phi-3 mini is already instruction-tuned with supervised fine-tuning (SFT) and likely RLHF, meaning it understands how to follow prompts and maintain conversational flow. This gives me a much better starting point than training from a base model. Note: Microsoft actually did not release the base model.</p>\n<p><strong>Ecosystem support</strong>:</p>\n<ul>\n<li>This <a href=\"https://gist.github.com/andrewssobral/89ca0cd40e609a32c0ce8241d01f484d\" target=\"_blank\" rel=\"noopener noreferrer\">code reference</a> gave me a working starting point</li>\n<li>There was an <a href=\"https://github.com/microsoft/PhiCookBook/blob/main/md/03.FineTuning/FineTuning_MLX.md\" target=\"_blank\" rel=\"noopener noreferrer\">official cookbook</a> with best practices</li>\n<li>There was a good <a href=\"https://huggingface.co/microsoft/Phi-3-mini-4k-instruct\" target=\"_blank\" rel=\"noopener noreferrer\">model card on Hugging Face</a> with clear usage example</li>\n</ul>\n<br>\n<p><strong>Hardware compatibility</strong>: With my M3 Max and 48GB RAM, this model fits comfortably in memory with room for LoRA adapters and training overhead.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"finetuning-technique\">Finetuning Technique<a href=\"https://didierlopes.com/blog/fine-tuning-a-llm-on-my-blog-posts#finetuning-technique\" class=\"hash-link\" aria-label=\"Direct link to Finetuning Technique\" title=\"Direct link to Finetuning Technique\">​</a></h3>\n<p>Traditional fine-tuning updates all 3.8 billion parameters, requiring enormous compute resources and risking catastrophic forgetting (where the model loses its general capabilities while learning your specific data).</p>\n<p><strong>LoRA's elegant solution</strong>: Low-Rank Adaptation works by decomposing weight updates into smaller matrices. Instead of modifying a large weight matrix W directly, LoRA adds two smaller matrices <code>A</code> and <code>B</code> such that the update becomes <code>W + BA</code>, where <code>B</code> has rank <code>r</code> and <code>r &lt;&lt; d</code> (with <code>d</code> being the original dimensions). More on LoRA <a href=\"https://huggingface.co/docs/peft/developer_guides/lora\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-09-02-fine-tuning-a-llm-on-my-blog-posts_2.webp\"></p>\n<p>Why this matters:</p>\n<ul>\n<li><strong>Parameter efficiency</strong>: I'm only training a small percentage (<code>&lt;0.2%</code>) of the entire 3.8b model</li>\n<li><strong>Memory efficiency</strong>: Base model stays frozen, only adapter weights need gradients</li>\n<li><strong>Modularity</strong>: Can swap different LoRA adapters for different tasks/personalities</li>\n<li><strong>Reduced overfitting</strong>: Smaller parameter space makes it harder to memorize training data (which also validates the fact that fine-tuning is not best choice to give more information to a model)</li>\n</ul>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"framework\">Framework<a href=\"https://didierlopes.com/blog/fine-tuning-a-llm-on-my-blog-posts#framework\" class=\"hash-link\" aria-label=\"Direct link to Framework\" title=\"Direct link to Framework\">​</a></h3>\n<p>MLX is specifically designed for Apple's unified memory architecture. While PyTorch can run on Mac, it wasn't built with Apple Silicon's unique characteristics in mind.</p>\n<p>Key MLX benefits:</p>\n<ul>\n<li><strong>Memory efficiency</strong>: Unified memory means no CPU/GPU transfers, LoRA adapters and base model share the same memory pool efficiently</li>\n<li><strong>Lazy evaluation</strong>: Only computes what's needed, when it's needed - crucial for memory-constrained fine-tuning</li>\n<li><strong>Native optimization</strong>: Built for Apple's AMX (Apple Matrix Extensions) and Neural Engine integration</li>\n</ul>\n<p>Most production fine-tuning still happens on NVIDIA GPUs with PyTorch. But for Apple Silicon users, MLX offers several advantages:</p>\n<ul>\n<li><strong>Lower barrier to entry</strong>: No need for cloud GPUs or expensive NVIDIA hardware</li>\n<li><strong>Rapid experimentation</strong>: Faster iteration cycles for smaller models</li>\n<li><strong>Privacy</strong>: Everything runs locally, no data leaves your machine</li>\n</ul>\n<p>Note that I was able to do this because I was working with a &lt;10B parameter model and had Apple Silicon with 48GB RAM. But more importantly, this was done for experimentation, and not production - so I chose what allowed me to get my hands dirty faster.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"1-preparing-the-data\">1. Preparing the data<a href=\"https://didierlopes.com/blog/fine-tuning-a-llm-on-my-blog-posts#1-preparing-the-data\" class=\"hash-link\" aria-label=\"Direct link to 1. Preparing the data\" title=\"Direct link to 1. Preparing the data\">​</a></h2>\n<p>Code can be found here: <a href=\"https://github.com/DidierRLopes/fine-tune-llm/blob/main/scripts/01_prepare_data.py\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/DidierRLopes/fine-tune-llm/blob/main/scripts/01_prepare_data.py</a>.</p>\n<p>For the data we will be using a <a href=\"https://huggingface.co/datasets/didierlopes/my-blog-qa-dataset\" target=\"_blank\" rel=\"noopener noreferrer\">Q&amp;A dataset based on my blogposts</a>. The repository where I turned my blog posts into this dataset can be found <a href=\"https://github.com/DidierRLopes/turn-blog-feed-into-qa-dataset/tree/main\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-09-02-fine-tuning-a-llm-on-my-blog-posts_3.webp\"></p>\n<p>The dataset contains 91 blog posts transformed into conversational Q&amp;A pairs - roughly 2,100 exchanges covering everything from OpenBB's journey to technical deep-dives on open source.</p>\n<p>Each entry in the dataset contains conversations with user questions and my responses. But raw conversational data (which I parsed from a blogpost) isn't something you can just throw at a model. It needs structure, and more importantly, <strong>it needs the right structure</strong> for your chosen model.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"formatting-for-phi-3-mini-4k-instruct\">Formatting for phi-3-mini-4k-instruct<a href=\"https://didierlopes.com/blog/fine-tuning-a-llm-on-my-blog-posts#formatting-for-phi-3-mini-4k-instruct\" class=\"hash-link\" aria-label=\"Direct link to Formatting for phi-3-mini-4k-instruct\" title=\"Direct link to Formatting for phi-3-mini-4k-instruct\">​</a></h3>\n<p>Phi-3-mini-4k-instruct has been trained with a specific chat template, and we need to follow it - otherwise results won't be optimal (this was one of my first mistakes!)</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-09-02-fine-tuning-a-llm-on-my-blog-posts_4.webp\"></p>\n<p>You can find that template in the model card on HF: <a href=\"https://huggingface.co/microsoft/Phi-3-mini-4k-instruct\" target=\"_blank\" rel=\"noopener noreferrer\">https://huggingface.co/microsoft/Phi-3-mini-4k-instruct</a></p>\n<p>Important: Since this is an instruct model, then it is important to retain the system prompt on the training samples. (I also did a mistake here!)</p>\n<p>Example:</p>\n<div class=\"language-text codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-text codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">&lt;|system|&gt;</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">You are a helpful assistant.&lt;|end|&gt;</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">&lt;|user|&gt;</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">How to explain Internet for a medieval knight?&lt;|end|&gt;</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">&lt;|assistant|&gt;</span><br></span></code></pre></div></div>\n<p>Those special tokens (<code>&lt;|system|&gt;</code>, <code>&lt;|user|&gt;</code>, <code>&lt;|assistant|&gt;</code>, <code>&lt;|end|&gt;</code>) aren't decorative, they're semantic markers that tell the model exactly where each part of the conversation begins and ends. (Do not forget these, and ensure there are no typos! I did not do a mistake here ehe)</p>\n<p>I actually added a function to validate if the required tokens existed, and are in the right order.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"training-split\">Training split<a href=\"https://didierlopes.com/blog/fine-tuning-a-llm-on-my-blog-posts#training-split\" class=\"hash-link\" aria-label=\"Direct link to Training split\" title=\"Direct link to Training split\">​</a></h3>\n<p>One of the most common mistakes in fine-tuning is treating your test data as validation data. Here's how I split the ~2,100 samples:</p>\n<ul>\n<li><strong>Training (80%, ~1,700 samples)</strong>: The model learns from these</li>\n<li><strong>Validation (10%, ~210 samples)</strong>: Monitors training progress in real-time.<!-- -->\n<ul>\n<li>In typical ML systems, this is used to tweak hyper parameters. In this case it checks the validation loss during training - and allows you to avoid overfitting, by making sure that training loss doesn’t diverge from validation loss.</li>\n</ul>\n</li>\n<li><strong>Test (10%, ~210 samples)</strong>: Final evaluation, never touched during training</li>\n</ul>\n<p>But before splitting, I <strong>shuffle all samples from all conversations</strong>. This avoids temporal bias where training data represents one era of thinking while test data represents another.</p>\n<p>One of the reasons for which I recommend displaying the number of samples is so that you can put yourself in the shoes of the model to understand how many samples it will see; and that will help you make better decisions in terms of the training and model configs.</p>\n<details class=\"details_lb9f alert alert--info details_b_Ee\" data-collapsed=\"true\"><summary>Preparing data logs</summary><div><div class=\"collapsibleContent_i85q\"><div class=\"language-bash codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-bash codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">$ python scripts/01_prepare_data.py --config config/data_config.yaml</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">============================================================</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">DATA PREPARATION PIPELINE</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">============================================================</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">&gt;&gt;&gt; Step 1: Loading raw dataset...</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Loading dataset: didierlopes/my-blog-qa-dataset</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Dataset loaded successfully. Available splits: ['train']</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Dataset size: 91 samples</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Dataset features: {'title': Value('string'), 'conversation': List({'content': Value('string'), 'role': Value('string')}), 'context': Value('string'), 'url': Value('string'), 'date': Value('string')}</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">&gt;&gt;&gt; Step 2: Processing and formatting data...</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Starting data preprocessing...</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Extracted 2129 conversation samples</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Data split created:</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Training samples: 1705 (80.1%)</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Validation samples: 212 (10.0%)</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Test samples: 212 (10.0%)</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Data preprocessing completed successfully!</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">&gt;&gt;&gt; Step 3: Validating processed data...</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Validating training data...</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Validating 10 samples...</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">📊 Validation Summary:</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Total samples checked: 10</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Valid samples:         10</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Invalid samples:       0</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Validation rate:       100.0%</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">✅ All samples passed validation!</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Validating validation data...</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Validating 10 samples...</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">📊 Validation Summary:</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Total samples checked: 10</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Valid samples:         10</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Invalid samples:       0</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Validation rate:       100.0%</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">✅ All samples passed validation!</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Validating test data...</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Validating 10 samples...</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">📊 Validation Summary:</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Total samples checked: 10</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Valid samples:         10</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Invalid samples:       0</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Validation rate:       100.0%</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">✅ All samples passed validation!</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Sample statistics:</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">📈 Sample Statistics:</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Total samples:     2,129</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Average length:    721 characters</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Min length:        340 characters</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Max length:        3,880 characters</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Total characters:  1,536,016</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">&gt;&gt;&gt; Step 4: Saving processed data...</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Training data saved to: data/processed/train.json</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Validation data saved to: data/processed/val.json</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Test data saved to: data/processed/test.json</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Data statistics saved to: data/processed/data_stats.json</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Training data: data/processed/train.json</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Validation data: data/processed/val.json</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Test data: data/processed/test.json</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Statistics: data/processed/data_stats.json</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Training samples: 1705</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Validation samples: 212</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Test samples: 212</span><br></span></code></pre></div></div></div></div></details>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"2-train-the-model\">2. Train the model<a href=\"https://didierlopes.com/blog/fine-tuning-a-llm-on-my-blog-posts#2-train-the-model\" class=\"hash-link\" aria-label=\"Direct link to 2. Train the model\" title=\"Direct link to 2. Train the model\">​</a></h2>\n<p>Code can be found here: <a href=\"https://github.com/DidierRLopes/fine-tune-llm/blob/main/scripts/02_train_model.py\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/DidierRLopes/fine-tune-llm/blob/main/scripts/02_train_model.py</a>.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"model-configuration\">Model configuration<a href=\"https://didierlopes.com/blog/fine-tuning-a-llm-on-my-blog-posts#model-configuration\" class=\"hash-link\" aria-label=\"Direct link to Model configuration\" title=\"Direct link to Model configuration\">​</a></h3>\n<div class=\"language-yaml codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-yaml codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">  </span><span class=\"token key atrule\">base_model</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    </span><span class=\"token key atrule\">path</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"microsoft/Phi-3-mini-4k-instruct\"</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">  </span><span class=\"token key atrule\">lora</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    </span><span class=\"token key atrule\">num_layers</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"> </span><span class=\"token number\">32</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    </span><span class=\"token key atrule\">lora_layers</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"> </span><span class=\"token number\">32</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    </span><span class=\"token key atrule\">rank</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"> </span><span class=\"token number\">16</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    </span><span class=\"token key atrule\">scale</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"> </span><span class=\"token number\">20.0</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    </span><span class=\"token key atrule\">dropout</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"> </span><span class=\"token number\">0.1</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    </span><span class=\"token key atrule\">keys</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">      </span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">-</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"self_attn.q_proj\"</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">      </span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">-</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"self_attn.k_proj\"</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">      </span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">-</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"self_attn.v_proj\"</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">      </span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">-</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"self_attn.o_proj\"</span><br></span></code></pre></div></div>\n<h4 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"lora-layers\">Lora layers<a href=\"https://didierlopes.com/blog/fine-tuning-a-llm-on-my-blog-posts#lora-layers\" class=\"hash-link\" aria-label=\"Direct link to Lora layers\" title=\"Direct link to Lora layers\">​</a></h4>\n<p>From <a href=\"https://huggingface.co/microsoft/Phi-3-mini-4k-instruct/blob/main/config.json\" target=\"_blank\" rel=\"noopener noreferrer\">phi-3-mini-4k-instruct config file</a> we know that it has 32 hidden layers (i.e. 32 transformer blocks comprised of multi-head self-attention, feed-forward network, and residual connections + layer norms).</p>\n<p>In transformer models like Phi-3, different layers learn different levels of abstraction:</p>\n<ul>\n<li><strong>Bottom layers (1-10) - \"grammar\"</strong>: Learn fundamental language patterns - grammar, syntax, basic word associations. These layers understand that \"CEO\" is a noun, that it often precedes \"of\", and basic sentence structure.</li>\n<li><strong>Middle layers (11-20) - \"reasoning\"</strong>: Build conceptual understanding - connecting ideas, understanding context, domain knowledge. These layers learn that \"OpenBB\" relates to \"finance\" and \"open source\", that \"Terminal\" in my context means a financial analysis tool, not a computer interface.</li>\n<li><strong>Top layers (21-32) - \"style &amp; expression\"</strong>: Handle vocabulary selection and style - choosing specific words, maintaining tone, formatting responses. These layers decide whether to say \"leverage\" vs \"use\", whether to include technical details, how to structure explanations.</li>\n</ul>\n<p>Most fine-tuning tutorials suggest only adapting the top 8-16 layers because it's more memory-efficient and often sufficient for simple style transfer. But my writing isn't just about word choice - it's about how I conceptually approach topics:</p>\n<ul>\n<li>When I discuss technical topics, I ground them in practical examples (middle layers)</li>\n<li>I have specific patterns of explanation - starting broad, then diving deep (bottom-middle layers)</li>\n<li>My sentence construction tends toward clarity over complexity (bottom layers)</li>\n</ul>\n<p>Also, I often change the order of the words due to Portuguese being my primary language - although not correct, ultimately I’m trying to fine-tune a model to represent my writing better. So, in this case, I adapted all 32 layers.</p>\n<p>Although this happened when I was fine-tuning those 3.1M parameters 😭</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-09-02-fine-tuning-a-llm-on-my-blog-posts_5.webp\"></p>\n<hr>\n<h4 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"attention-matrices\">Attention matrices<a href=\"https://didierlopes.com/blog/fine-tuning-a-llm-on-my-blog-posts#attention-matrices\" class=\"hash-link\" aria-label=\"Direct link to Attention matrices\" title=\"Direct link to Attention matrices\">​</a></h4>\n<p>In LoRA, the matrices you can adapt are:</p>\n<ul>\n<li><strong>Attention projections</strong>: Query, Key, Value, Output<!-- -->\n<ul>\n<li>This is the most common and impactful, it changes which tokens pay attention to which and how strongly. Ultimately, this is where the reasoning comes from.</li>\n</ul>\n</li>\n<li><strong>Feed-forward (MLP) projections</strong>: W1, W2<!-- -->\n<ul>\n<li>Changes how representations are transformed nonlinearly - not the most common</li>\n</ul>\n</li>\n<li><strong>Embeddings &amp; LM head</strong>: token embedding matrix and output head<!-- -->\n<ul>\n<li>Almost never adapted</li>\n</ul>\n</li>\n</ul>\n<p>We went with the attention projections to adapt the complete attention mechanism. Picking FFN matrices would make adapters 2-3x larger, and I didn’t think it was worth it.</p>\n<hr>\n<h4 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"rank\">Rank<a href=\"https://didierlopes.com/blog/fine-tuning-a-llm-on-my-blog-posts#rank\" class=\"hash-link\" aria-label=\"Direct link to Rank\" title=\"Direct link to Rank\">​</a></h4>\n<p>LoRA works by adding to a big weight matrix of dimension <code>d x d</code>, and adapted weight matrix of dimension <code>(d,d)</code> - where <code>d</code> is the hidden_size and can be found in model config, in our case, <code>3072</code>.</p>\n<p>So wait, LoRA adds a matrix of size <code>3072 × 3072</code>?</p>\n<p>Yes and no.</p>\n<p>It does, but in a smart way - and this is where <strong>rank</strong> comes into play.</p>\n<p>LoRA adapts two matrices called <code>A</code> and <code>B</code>, where <code>A</code> is of dimension <code>(d,r)</code> and <code>B</code> is of dimension <code>(r,d)</code>. The <code>r</code> value is the <strong>rank</strong>. And although multiplying these matrices results in a matrix of size <code>(d,d)</code>, the number of parameters on <code>A</code> and <code>B</code> combined is <code>2dr</code>.</p>\n<p>So,</p>\n<ul>\n<li><strong>Low rank (small r</strong>), LoRA can only make coarse adjustments (cheap, fast).</li>\n<li><strong>High rank (large r)</strong>, LoRA can make finer adjustments (better fidelity, but heavier).</li>\n</ul>\n<p>I actually started with 8 on this one, but results weren’t the best so I doubled it.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-09-02-fine-tuning-a-llm-on-my-blog-posts_6.webp\"></p>\n<p>Note: The <code>AxB</code> multiplication that happens which results in the new <code>W</code> matrix adapter is normalized by <code>r</code>. This makes it so the update’s magnitude stays roughly stable regardless of rank, otherwise <code>r</code> would linearly increase variance of the update.</p>\n<hr>\n<h4 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"scale\">Scale<a href=\"https://didierlopes.com/blog/fine-tuning-a-llm-on-my-blog-posts#scale\" class=\"hash-link\" aria-label=\"Direct link to Scale\" title=\"Direct link to Scale\">​</a></h4>\n<p>What if you actually wanted there to be higher variance of the update?</p>\n<p>As in, you wanted LoRA update to influence even more the frozen weight?</p>\n<p>This is where the <strong>scale</strong> parameter <code>α</code> comes into play.</p>\n<ul>\n<li><strong>Small scale α</strong>: LoRA update has a subtle effect.</li>\n<li><strong>Large scale α</strong>: LoRA update dominates more strongly.</li>\n</ul>\n<p>Most PyTorch examples use <code>1.0</code>-<code>5.0</code>, but MLX's implementation benefits from higher scales - the community suggests <code>2 * rank</code> as a rule of thumb, so that LoRA adapters weights don’t get drowned out by the base model frozen weights.</p>\n<hr>\n<h4 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"dropout\">Dropout<a href=\"https://didierlopes.com/blog/fine-tuning-a-llm-on-my-blog-posts#dropout\" class=\"hash-link\" aria-label=\"Direct link to Dropout\" title=\"Direct link to Dropout\">​</a></h4>\n<p>Dropout <code>p</code> is cheap insurance against overfitting when your fine-tune dataset is narrow (e.g., aligning a model to one person’s writing style) or you have a small dataset (e.g. a few thousand samples). It works by randomly zeroing out parts of the low-rank update with probability <code>p</code> (0-1).</p>\n<ul>\n<li><strong>Too much dropout</strong>: Slows learning (adapter doesn’t specialize enough).</li>\n<li><strong>Too little dropout</strong>: Adapter memorizes quirks instead of general style.</li>\n</ul>\n<p>If dataset is huge (not our case lol), often the dropout is skipped altogether since there isn’t the risk of overfitting (I mean it depends on the model a bit, but yea).</p>\n<p>We went with <code>0.1</code>, which falls under the recommendation.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"training-configuration\">Training Configuration<a href=\"https://didierlopes.com/blog/fine-tuning-a-llm-on-my-blog-posts#training-configuration\" class=\"hash-link\" aria-label=\"Direct link to Training Configuration\" title=\"Direct link to Training Configuration\">​</a></h3>\n<div class=\"language-yaml codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-yaml codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token key atrule\">training</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">  </span><span class=\"token key atrule\">iters</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"> </span><span class=\"token number\">2000</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">  </span><span class=\"token key atrule\">batch_size</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"> </span><span class=\"token number\">4</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">  </span><span class=\"token key atrule\">learning_rate</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"> </span><span class=\"token number\">1e-5</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">  </span><span class=\"token key atrule\">steps_per_eval</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"> </span><span class=\"token number\">50</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">  </span><span class=\"token key atrule\">grad_checkpoint</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"> </span><span class=\"token boolean important\">true</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">  </span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\"></span><span class=\"token key atrule\">optimizer</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">  </span><span class=\"token key atrule\">type</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"adam\"</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">  </span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\"></span><span class=\"token key atrule\">metrics</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">  </span><span class=\"token key atrule\">patience</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"> </span><span class=\"token number\">5</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">  </span><span class=\"token key atrule\">min_delta</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"> </span><span class=\"token number\">0.001</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">  </span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\"></span><span class=\"token key atrule\">paths</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">  </span><span class=\"token key atrule\">train_data</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"data/processed/train.json\"</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">  </span><span class=\"token key atrule\">test_data</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"data/processed/test.json\"</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">  </span><span class=\"token key atrule\">logs_dir</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"logs/training\"</span><br></span></code></pre></div></div>\n<p>The training hyperparameters rationale:</p>\n<ul>\n<li>\n<p><strong>Batch size 4</strong>: Larger batches (8-16) provide more stable gradients but require more memory and can miss fine details. Smaller batches (1-2) are noisy. 4 felt like a good sweet spot.</p>\n<ul>\n<li>With ~1,700 training samples and batch size 4, that means that there are 425 steps/epoch. An epoch corresponds to a full pass through the training dataset.</li>\n</ul>\n</li>\n<li>\n<p><strong>2000 iterations</strong>: With 425 steps per epoch and 2000 total steps, that means that there are roughly 5 epochs.</p>\n<ul>\n<li>This means that the model has seen each of the 1,700 examples ~5 times (in slightly different shuffles).</li>\n<li>If you kept training further (10–20 epochs), you risk overfitting, memorizing samples instead of generalizing.</li>\n</ul>\n</li>\n<li>\n<p><strong>Adam</strong> stands for <strong>Adaptive Momentum Estimation</strong>, it is one of the model widely used optimizers in deep learning, and an extension of stochastic gradient descent (SGD). This was an easy choice.</p>\n<ul>\n<li>Adaptive - each parameter gets its own learning rate (scaled by gradient history).</li>\n<li>Momentum - smooths updates, prevents oscillations.</li>\n<li>Automatic scaling - no need to tune learning rate schedules as much as vanilla SGD.</li>\n</ul>\n</li>\n<li>\n<p><strong>Learning rate 1e-5</strong>: This controls how big each update step is when adjusting parameters during training. Luckily, there are good rules of thumbs for this value in LoRA / LLM fine-tuning:</p>\n<ul>\n<li>Full fine-tunes (big models): 1e-5 to 1e-4</li>\n<li>LoRA fine-tunes (small adapters): 1e-5 is a very common sweet spot</li>\n<li>If unstable: drop to 5e-6 or even 1e-6</li>\n<li>If underfitting (loss barely moving): try 2e-5 or 3e-5</li>\n</ul>\n</li>\n<li>\n<p><strong>Evaluation every 50 steps</strong>: Frequent enough to catch overfitting early (40 checks across training), but not so frequent that it slows training.</p>\n<ul>\n<li>Each evaluation on 210 validation samples takes ~30 seconds.</li>\n</ul>\n</li>\n<li>\n<p><strong>Gradient checkpointing</strong> is a memory-saving technique that reduces GPU usage during training by only storing a subset of intermediate activations in the forward pass. When the backward pass runs, the missing activations are recomputed on the fly, which increases compute time but dramatically lowers memory requirements.</p>\n<ul>\n<li>Frees up memory so we can fit a batch size of 4 instead of 2, improving gradient stability.</li>\n<li>The ~20% slower training is a reasonable trade-off compared to the benefits.</li>\n</ul>\n</li>\n<li>\n<p><strong>Early stopping (patience 5 and min delta 0.001)</strong>: If validation loss doesn't improve by 0.001 for 5 consecutive evaluations (250 iterations), training halts.</p>\n</li>\n</ul>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"the-training-process\">The training process<a href=\"https://didierlopes.com/blog/fine-tuning-a-llm-on-my-blog-posts#the-training-process\" class=\"hash-link\" aria-label=\"Direct link to The training process\" title=\"Direct link to The training process\">​</a></h3>\n<p align=\"center\"><img width=\"1000\" src=\"https://didierlopes.com/blog/2025-09-02-fine-tuning-a-llm-on-my-blog-posts_7.webp\"></p>\n<p>Training isn't just about pressing \"run\" and waiting. It's an active process of monitoring, adjusting, and sometimes killing runs that aren't working.</p>\n<p>Let me walk you through what's actually happening when we fine-tune the model:</p>\n<ol>\n<li>Load base Phi-3 model (3.8B parameters)</li>\n<li>Freeze base model weights - these never change</li>\n<li>Add LoRA adapters (3.1M trainable params, ~0.08% of total)</li>\n<li>Train only the adapters using validation for monitoring</li>\n</ol>\n<p>The magic here is that the training only updates the tiny LoRA matrices, but the combined output leverages the full 3.8B parameter knowledge base.</p>\n<p>During each forward pass, the frozen base model produces its output, and the LoRA adapters add their learned adjustments on top - scaled by a factor of 20.0 to make the adaptations significant enough to matter.</p>\n<p>In fact, every forward pass, the model processes 4 samples (batch_size), predicts the next tokens, and compares them to the actual tokens. The loss quantifies how wrong it was. Backpropagation then updates only the LoRA weights to reduce this loss.</p>\n<p>During backpropagation, gradients flow only to the LoRA adapters - the base model parameters never receive gradients and never change.</p>\n<p>Every 50 steps, I evaluate on validation data.</p>\n<ul>\n<li>Training loss dropping, validation loss dropping<!-- -->\n<ul>\n<li><strong>Learning</strong> - this is what you want! Model is learning from training data and generalizing to unseen validation data.</li>\n</ul>\n</li>\n<li>Training loss dropping, validation loss flat<!-- -->\n<ul>\n<li><strong>Approaching capacity</strong> - model is learning from the training data, but it’s no longer generalizing better to unseen data. The model is \"full\" with the representational flexibility given. This is different from underfitting, where the model wouldn’t even be learning more from the training data.</li>\n</ul>\n</li>\n<li>Training loss dropping, validation loss rising<!-- -->\n<ul>\n<li><strong>Overfitting</strong> - the model is “memorizing” training data examples. Time to stop, or early stoppage will take care of it.</li>\n</ul>\n</li>\n<li>Both losses flat<!-- -->\n<ul>\n<li>Learning rate too low or model saturated (and we need to go back to tweaking hyperparameters).</li>\n</ul>\n</li>\n</ul>\n<p>My training showed steady improvement until iteration ~1,500, where validation loss plateaued around 2.8. The training got halted here due to my patience-based early stoppage (patience 5 - i.e. 250 iterations, min delta 0.001). This saved me from overfitting and wasted compute on iterations 1,500-2,000 where no meaningful learning occurred.</p>\n<p>Ultimately, this told me the model had extracted what it could from the data.</p>\n<p>But what does a validation loss of 2.8 mean?</p>\n<p>Validation loss of 2.8 translates to a perplexity of ~16.4. This means on average, the model thinks there are about 16 equally likely next tokens at each step.</p>\n<p>For context, random guessing would be the vocabulary size (e.g. ~32,000) and a perfect model would have 1. So 16.4 is pretty good.</p>\n<p>Note: The 3.1M parameters aren't learning language from scratch - they're learning how to nudge an already-capable model toward our specific use case. That's why LoRA is so sample-efficient and why we can achieve good results with relatively small datasets.</p>\n<p>The base model retains all its general knowledge while the LoRA adapters inject domain-specific expertise. It's like having a general practitioner doctor (base model) who takes a specialized course (LoRA training) to better handle specific types of cases, without forgetting their general medical knowledge.</p>\n<p>Training is fundamentally about finding the right balance: enough learning to improve performance, but not so much that you overfit to your training data. The validation curve is your compass, and early stopping is your safety net.</p>\n<details class=\"details_lb9f alert alert--info details_b_Ee\" data-collapsed=\"true\"><summary>Training model logs</summary><div><div class=\"collapsibleContent_i85q\"><div class=\"language-bash codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-bash codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">$ python scripts/02_train_model.py --model-config config/model_config.yaml --training-config config/training_config.yaml --train-data data/processed/train.json --val-data data/processed/val.json --test-data data/processed/test.json</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">============================================================</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">MODEL TRAINING PIPELINE</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">============================================================</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Model config: config/model_config.yaml</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Training config: config/training_config.yaml</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Training data: data/processed/train.json</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Validation data: data/processed/val.json</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Test data: data/processed/test.json (for final evaluation only)</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Metrics logging to: logs/training</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">============================================================</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">STARTING FINE-TUNING PIPELINE</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">============================================================</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Loading training data from: data/processed/train.json</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Loading validation data from: data/processed/val.json</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Loaded 1705 training samples</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Loaded 212 validation samples</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Loading base model: microsoft/Phi-3-mini-4k-instruct</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Fetching 13 files: 100%|██████████████████████████████████████████████████████████████████████████████████████| 13/13 [00:00&lt;00:00, 46924.23it/s]</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Model loaded successfully</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">LoRA config saved to: models/adapters/adapter_config.json</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Freezing base model parameters...</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Converting linear layers to LoRA layers...</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">LoRA setup completed:</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Trainable parameters: 3,145,728 (0.08%)</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Total parameters:     3,824,225,280</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Setting up adam optimizer with learning rate: 1e-05</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">============================================================</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">TRAINING CONFIGURATION SUMMARY</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">============================================================</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">📊 Dataset:</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Training samples:   1705</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Validation samples: 212</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">🔧 LoRA Configuration:</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Layers to adapt:  32/32</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">LoRA rank:        16</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">LoRA scale:       20.0</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Dropout:          0.1</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Target layers:    self_attn.q_proj, self_attn.k_proj, self_attn.v_proj, self_attn.o_proj</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">📈 Training Parameters:</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Iterations:       2000</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Batch size:       4</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Learning rate:    1e-5</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Eval frequency:   50</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Grad checkpoint:  True</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Starting training...</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Training on 1705 samples</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Validating on 212 samples</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Starting training..., iters: 2000</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Iter 1: Val loss 2.399, Val took 12.519s</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Iteration 1: Val loss = 2.3986, Perplexity = 11.01</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">→ New best validation loss: 2.3986 (perplexity: 11.01)</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Iter 10: Train loss 2.242, Learning Rate 1.000e-05, It/sec 0.805, Tokens/sec 484.578, Trained Tokens 6021, Peak mem 8.924 GB</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Iteration 10: Train loss = 2.2423</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Iter 20: Train loss 1.522, Learning Rate 1.000e-05, It/sec 0.815, Tokens/sec 487.475, Trained Tokens 12004, Peak mem 8.924 GB</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Iteration 20: Train loss = 1.5223</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Iter 30: Train loss 1.319, Learning Rate 1.000e-05, It/sec 0.580, Tokens/sec 464.444, Trained Tokens 20014, Peak mem 11.472 GB</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Iteration 30: Train loss = 1.3188</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">(...)</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">============================================================</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">TRAINING SUMMARY</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">============================================================</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">📊 Training Completion:</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Total iterations:     200</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Early stopped:        True</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Final train loss:     0.9613</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Final val loss:       1.0499</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Best val loss:        1.0393</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Final perplexity:     2.86</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Best perplexity:      2.83</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">⚠️  Training stopped early due to lack of improvement</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\"> Patience counter reached: 24/5</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">📁 Output Files:</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Adapters: models/adapters/</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Training logs: logs/training/</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Metrics plot: logs/training/training_metrics.webp</span><br></span></code></pre></div></div></div></div></details>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"3-evaluate-the-model\">3. Evaluate the model<a href=\"https://didierlopes.com/blog/fine-tuning-a-llm-on-my-blog-posts#3-evaluate-the-model\" class=\"hash-link\" aria-label=\"Direct link to 3. Evaluate the model\" title=\"Direct link to 3. Evaluate the model\">​</a></h2>\n<p>Code can be found here: <a href=\"https://github.com/DidierRLopes/fine-tune-llm/blob/main/scripts/03_evaluate_model.py\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/DidierRLopes/fine-tune-llm/blob/main/scripts/03_evaluate_model.py</a>.</p>\n<p>The evaluation process answers a critical question:</p>\n<p><strong>Did the fine-tuning actually improve the model?</strong></p>\n<p>We compare two models:</p>\n<ol>\n<li><strong>Base model</strong>: The original Phi-3-mini-4k-instruct (our baseline)</li>\n<li><strong>Fine-tuned model</strong>: Base model + our trained LoRA adapters applied at runtime</li>\n</ol>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"step-1-loading-models-for-comparison\">Step 1: Loading models for comparison<a href=\"https://didierlopes.com/blog/fine-tuning-a-llm-on-my-blog-posts#step-1-loading-models-for-comparison\" class=\"hash-link\" aria-label=\"Direct link to Step 1: Loading models for comparison\" title=\"Direct link to Step 1: Loading models for comparison\">​</a></h3>\n<p>For the base model evaluation, you need need to load the original model from HF.</p>\n<div class=\"language-python codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-python codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">model</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> tokenizer </span><span class=\"token operator\">=</span><span class=\"token plain\"> load</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"microsoft/Phi-3-mini-4k-instruct\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><br></span></code></pre></div></div>\n<p>For the fine-tuned model evaluation, you need to load the original model from HF AND apply the adapters at runtime.</p>\n<div class=\"language-python codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-python codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">model</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> tokenizer </span><span class=\"token operator\">=</span><span class=\"token plain\"> load</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"microsoft/Phi-3-mini-4k-instruct\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token plain\"> model</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">freeze</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token plain\">  </span><span class=\"token comment\" style=\"color:rgb(98, 114, 164)\"># Freeze the base weights</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">linear_to_lora_layers</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token plain\">model</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> lora_config</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token plain\">  </span><span class=\"token comment\" style=\"color:rgb(98, 114, 164)\"># Add LoRA layers</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">model</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">load_weights</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"adapters.safetensors\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token plain\">  </span><span class=\"token comment\" style=\"color:rgb(98, 114, 164)\"># Load trained weights</span><br></span></code></pre></div></div>\n<p>We're not loading a completely different model file. We're taking the original model and applying the learned adapter weights on top of it at runtime.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"step-2-test-data-generation\">Step 2: Test data generation<a href=\"https://didierlopes.com/blog/fine-tuning-a-llm-on-my-blog-posts#step-2-test-data-generation\" class=\"hash-link\" aria-label=\"Direct link to Step 2: Test data generation\" title=\"Direct link to Step 2: Test data generation\">​</a></h3>\n<p>For each test question, both models generate responses.</p>\n<p>E.g. \"What is machine learning?\"</p>\n<div class=\"language-python codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-python codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">base_response </span><span class=\"token operator\">=</span><span class=\"token plain\"> generate</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token plain\">base_model</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> tokenizer</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> question</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> max_tokens</span><span class=\"token operator\">=</span><span class=\"token number\">200</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">finetuned_response </span><span class=\"token operator\">=</span><span class=\"token plain\"> generate</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token plain\">finetuned_model</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> tokenizer</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> question</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> max_tokens</span><span class=\"token operator\">=</span><span class=\"token number\">200</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><br></span></code></pre></div></div>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"step-3-measuring-performance\">Step 3: Measuring performance<a href=\"https://didierlopes.com/blog/fine-tuning-a-llm-on-my-blog-posts#step-3-measuring-performance\" class=\"hash-link\" aria-label=\"Direct link to Step 3: Measuring performance\" title=\"Direct link to Step 3: Measuring performance\">​</a></h3>\n<p>We utilized world overlap as a simple and interpretable metric. It compares predicted words vs reference answer words. Uses Jaccard similarity: overlap = intersection/union.</p>\n<p>Example:</p>\n<ul>\n<li>Reference: \"Machine learning uses algorithms and data\"</li>\n<li>Prediction: \"ML uses algorithms to learn from data\"</li>\n<li>Overlap: 4 words match out of 7 unique = 57%</li>\n</ul>\n<p>A better eval (out-of-scope for this work) would be to implement a version of LMArena where I would ask a question, and get two answers (one from base model and one from fine-tuned) and then I would select which one looked more like my writing without knowing which is which.</p>\n<details class=\"details_lb9f alert alert--info details_b_Ee\" data-collapsed=\"true\"><summary>Evaluate model logs</summary><div><div class=\"collapsibleContent_i85q\"><div class=\"language-bash codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-bash codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">$ python scripts/03_evaluate_model.py --config config/evaluation_config.yaml --test-data data/processed/test.json --adapters-path models/adapters --base-model microsoft/Phi-3-mini-4k-instruct</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">============================================================</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">MODEL EVALUATION PIPELINE</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">============================================================</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Standard evaluation: Base + Runtime LoRA Adapters</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">🔸 Step 1: Evaluating Base Model</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">============================================================</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">EVALUATING MODEL: base_model</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">============================================================</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Loading model: microsoft/Phi-3-mini-4k-instruct</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Fetching 13 files: 100%|██████████████████████████████████████████████████████████████████████████████████████| 13/13 [00:00&lt;00:00, 16008.79it/s]</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Model loaded successfully</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Loading test data from: data/processed/test.json</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Extracted 212 test questions</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Generating predictions for 212 questions...</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Generating predictions:   0%|  </span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">(...)</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Generating predictions: 100%|██████████████████████████████████████████████████████████████████████████████████| 212/212 [15:24&lt;00:00,  4.36s/it]</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Calculating metrics for 212 samples...</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Calculating word overlap scores...</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">============================================================</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">BASE_MODEL EVALUATION RESULTS</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">============================================================</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">📊 Word Overlap Metrics:</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Mean:    0.1574</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Median:  0.1586</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Std:     0.0443</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Range:   [0.0357, 0.2778]</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">📏 Length Statistics:</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Predictions: 864.6 chars (±163.1)</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">References:  405.8 chars (±186.8)</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">============================================================</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Metrics saved to: logs/evaluation/base_model_evaluation.json</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Evaluation completed! Results saved to: logs/evaluation/base_model_evaluation.json</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">🔸 Step 2: Evaluating Base Model + Runtime LoRA Adapters</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">============================================================</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">EVALUATING MODEL: lora_runtime (Base + LoRA Adapters)</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">============================================================</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Loading base model: microsoft/Phi-3-mini-4k-instruct</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Fetching 13 files: 100%|███████████████████████████████████████████████████████████████████████████████████████| 13/13 [00:00&lt;00:00, 3873.96it/s]</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Loading adapter config: models/adapters/adapter_config.json</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Freezing base model parameters...</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Applying LoRA adapters...</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Loading adapter weights: models/adapters/adapters.safetensors</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">✅ Model with LoRA adapters loaded successfully</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Trainable parameters: 3,145,728 (0.08%)</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Total parameters:     3,824,225,280</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Loading test data from: data/processed/test.json</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Extracted 212 test questions</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Generating predictions for 212 questions...</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Generating predictions:   0%|      </span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">(...)</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Generating predictions: 100%|██████████████████████████████████████████████████████████████████████████████████| 212/212 [07:19&lt;00:00,  2.07s/it]</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Calculating metrics for 212 samples...</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Calculating word overlap scores...</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">============================================================</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">LORA_RUNTIME EVALUATION RESULTS</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">============================================================</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">📊 Word Overlap Metrics:</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Mean:    0.2008</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Median:  0.2025</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Std:     0.0591</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Range:   [0.0449, 0.3913]</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">📏 Length Statistics:</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Predictions: 381.9 chars (±72.9)</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">References:  405.8 chars (±186.8)</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">============================================================</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Metrics saved to: logs/evaluation/lora_runtime_evaluation.json</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Evaluation completed! Results saved to: logs/evaluation/lora_runtime_evaluation.json</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">🔸 Step 3: Model Comparison</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">============================================================</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">MODEL COMPARISON</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">============================================================</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">📊 Model Performance Comparison:</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">------------------------------------------------------------</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Rank   Model                     Score           Metric         </span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">------------------------------------------------------------</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">1      lora_runtime              0.2008        Word Overlap</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">2      base_model                0.1574        Word Overlap</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">------------------------------------------------------------</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">🎯 Best Model (lora_runtime) vs Baseline (base_model):</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Score Improvement: +27.6%</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">base_model: 0.1574</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">lora_runtime: 0.2008</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">============================================================</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Score comparison plot saved to: logs/evaluation/word_overlap_comparison.webp</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Score distribution plot saved to: logs/evaluation/word_overlap_distributions.webp</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">2025-08-18 01:11:15.187 python3[94401:196290991] The class 'NSSavePanel' overrides the method identifier.  This method is implemented by class 'NSWindow'</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Comparison report saved to: logs/evaluation/model_comparison_report.json</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">📊 Detailed comparison plots saved to: logs/evaluation/model_comparison_report.json</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">============================================================</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">EVALUATION PIPELINE COMPLETED!</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">============================================================</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">📁 Output files:</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Evaluation results: logs/evaluation/</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Comparison plots: logs/evaluation/</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">🎉 Evaluation completed! Check the results in the logs directory.</span><br></span></code></pre></div></div></div></div></details>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"results-and-statistical-analysis\">Results and statistical analysis<a href=\"https://didierlopes.com/blog/fine-tuning-a-llm-on-my-blog-posts#results-and-statistical-analysis\" class=\"hash-link\" aria-label=\"Direct link to Results and statistical analysis\" title=\"Direct link to Results and statistical analysis\">​</a></h2>\n<p align=\"center\"><img width=\"800\" src=\"https://didierlopes.com/blog/2025-09-02-fine-tuning-a-llm-on-my-blog-posts_8.webp\"></p>\n<p>The evaluation results tell a compelling story about the effectiveness of our LoRA fine-tuning approach.</p>\n<hr>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"performance-improvement\">Performance improvement<a href=\"https://didierlopes.com/blog/fine-tuning-a-llm-on-my-blog-posts#performance-improvement\" class=\"hash-link\" aria-label=\"Direct link to Performance improvement\" title=\"Direct link to Performance improvement\">​</a></h3>\n<ul>\n<li><strong>Base model</strong>: 0.1574 word overlap (15.74%)</li>\n<li><strong>FT model</strong>: 0.2008 word overlap (20.08%)</li>\n</ul>\n<p>Improvement: +27.6% better performance</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"consistency-analysis\">Consistency analysis<a href=\"https://didierlopes.com/blog/fine-tuning-a-llm-on-my-blog-posts#consistency-analysis\" class=\"hash-link\" aria-label=\"Direct link to Consistency analysis\" title=\"Direct link to Consistency analysis\">​</a></h3>\n<ul>\n<li><strong>Base model std dev</strong>: 0.0443 (relatively consistent but limited)</li>\n<li><strong>FT std dev</strong>: 0.0591 (slightly more variable, but higher overall performance)</li>\n</ul>\n<p>The increased standard deviation in the fine-tuned model actually tells a positive story. While the base model gives consistently mediocre responses, our fine-tuned model shows more range - it's capable of both the baseline performance and significantly better responses.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"range-expansion\">Range expansion<a href=\"https://didierlopes.com/blog/fine-tuning-a-llm-on-my-blog-posts#range-expansion\" class=\"hash-link\" aria-label=\"Direct link to Range expansion\" title=\"Direct link to Range expansion\">​</a></h3>\n<ul>\n<li><strong>Base model range</strong>: [0.0357, 0.2778]</li>\n<li><strong>FT range</strong>: [0.0449, 0.3913]</li>\n</ul>\n<p>The fine-tuned model's maximum score (0.3913) significantly exceeds the base model's best performance (0.2778). This 41% jump in peak performance shows the model learned to generate responses that better match the reference style and content.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"length-analysis\">Length analysis<a href=\"https://didierlopes.com/blog/fine-tuning-a-llm-on-my-blog-posts#length-analysis\" class=\"hash-link\" aria-label=\"Direct link to Length analysis\" title=\"Direct link to Length analysis\">​</a></h3>\n<ul>\n<li><strong>Reference Length</strong>: 405.8 characters (±186.8)</li>\n<li><strong>Base model</strong>: 864.6 characters (±163.1) - verbose, unfocused</li>\n<li><strong>FT model</strong>: 381.9 characters (±72.9) - concise, targeted</li>\n</ul>\n<p>This is perhaps the most telling insight. The base model generates responses that are 2.2x longer than the references, suggesting verbose, unfocused answers.</p>\n<p>The fine-tuned model produces responses much closer to the reference length (381.9 vs 405.8 characters), with lower variability (±72.9 vs ±163.1), indicating it learned the appropriate response style and length.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"parameter-efficiency\">Parameter efficiency<a href=\"https://didierlopes.com/blog/fine-tuning-a-llm-on-my-blog-posts#parameter-efficiency\" class=\"hash-link\" aria-label=\"Direct link to Parameter efficiency\" title=\"Direct link to Parameter efficiency\">​</a></h3>\n<ul>\n<li>Total parameters: 3.82B</li>\n<li>Trainable parameters: 3.15M (0.08%)</li>\n<li>Performance gain: +27.6%</li>\n</ul>\n<p>We achieved nearly 28% better performance by training just 0.08% of the model's parameters. This represents exceptional parameter efficiency - roughly 345% improvement per percentage point of parameters trained.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"statistical-interpretation\">Statistical interpretation<a href=\"https://didierlopes.com/blog/fine-tuning-a-llm-on-my-blog-posts#statistical-interpretation\" class=\"hash-link\" aria-label=\"Direct link to Statistical interpretation\" title=\"Direct link to Statistical interpretation\">​</a></h3>\n<p>What 20.08% Word Overlap Actually Means: In a 100-word response, our fine-tuned model shares about 20 words with the reference answer. While this might seem low, it's actually strong performance because:</p>\n<ul>\n<li><strong>Multiple valid phrasing</strong>: \"quick\" vs \"fast\", \"big\" vs \"large\"</li>\n<li><strong>Different valid approaches</strong>: Same facts, different explanations</li>\n<li><strong>Context variations</strong>: References are specific examples, predictions are generalizations</li>\n</ul>\n<p>The key insight is relative improvement. The base model achieved 15.74% overlap - our fine-tuning pushed this to 20.08%, crossing an important threshold where responses become noticeably more aligned with expected answers.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"vibe-checking\">Vibe checking<a href=\"https://didierlopes.com/blog/fine-tuning-a-llm-on-my-blog-posts#vibe-checking\" class=\"hash-link\" aria-label=\"Direct link to Vibe checking\" title=\"Direct link to Vibe checking\">​</a></h2>\n<p>Results and statistics are great, but there’s nothing like actually playing with the models and vibe check results. This is why I created <a href=\"https://github.com/DidierRLopes/fine-tune-llm/blob/main/scripts/interactive_chat.py\" target=\"_blank\" rel=\"noopener noreferrer\">interactive_chat.py file</a>, so that we can ask a question - and we get responses from the base model but also fine-tuned model (and fused if it exists).</p>\n<p><em><strong>Prompt: \"What is machine learning?\"</strong></em></p>\n<p><strong>Base model</strong>: <em>\"Machine learning is a subset of artificial intelligence (AI) that focuses on the development of computer programs and algorithms that can access data and use it to learn for themselves. In machine learning, algorithms use computational methods to identify patterns in data, learn from those patterns, and then make decisions or predictions based on the data they've studied.</em></p>\n<p><em>There are three main types of machine learning: supervised learning, unsupervised learning, and reinforcement learning.</em></p>\n<p><em>1. Supervised learning: In this approach, the algorithm is trained on a labeled dataset, meaning that the input data is paired with the desired output. The algorithm learns to map input data to output data based on this training. The goal is to create a model that can accurately predict the output for new, unseen data. Examples of supervised learning include classification (predicting a category or label) and regression (predicting a numerical value).</em></p>\n<p><em>2. Unsupervised learning\"</em></p>\n<p><strong>LoRA runtime (base + adapters)</strong>: <em>Machine learning is a subfield of artificial intelligence that focuses on the development of algorithms and statistical models to enable computers to learn and improve from data, without being explicitly programmed. It encompasses techniques such as supervised learning, unsupervised learning, and reinforcement learning, which enable systems to make predictions, detect patterns, and make decisions based on large amounts of data.</em></p>\n<p><strong>Fused model</strong>: <em>Machine learning is a field of computer science that focuses on building algorithms capable of learning and improving from data, without explicit programming. It involves developing models that can make predictions or decisions based on input data, often through complex statistical techniques and mathematical optimization.</em></p>\n<details class=\"details_lb9f alert alert--info details_b_Ee\" data-collapsed=\"true\"><summary>Interactive chat logs</summary><div><div class=\"collapsibleContent_i85q\"><div class=\"language-bash codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-bash codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">$ python scripts/interactive_chat.py</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">============================================================</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">INTERACTIVE CHAT INTERFACE</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">============================================================</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Mode: COMPARE</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">🔸 Loading base model...</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Fetching 13 files: 100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 13/13 [00:00&lt;00:00, 51198.08it/s]</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">✅ Base model loaded</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">🔸 Loading LoRA runtime (base + adapters)...</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Fetching 13 files: 100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 13/13 [00:00&lt;00:00, 38130.04it/s]</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">✅ LoRA runtime loaded</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">🔸 Loading fused model...</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">✅ Fused model loaded</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">✅ Loaded 3 models: ['base', 'lora_runtime', 'fused']</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">============================================================</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">INTERACTIVE COMPARISON MODE</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">============================================================</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Type your prompts to compare model responses.</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Commands: 'quit' to exit, 'clear' to clear screen</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">------------------------------------------------------------</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">👤 You: What is machine learning</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">🤖 Generating from base...</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">🤖 Generating from lora_runtime...</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">🤖 Generating from fused...</span><br></span></code></pre></div></div></div></div></details>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"model-on-hugging-face\">Model on Hugging Face<a href=\"https://didierlopes.com/blog/fine-tuning-a-llm-on-my-blog-posts#model-on-hugging-face\" class=\"hash-link\" aria-label=\"Direct link to Model on Hugging Face\" title=\"Direct link to Model on Hugging Face\">​</a></h2>\n<p>Finally, using the <a href=\"https://github.com/DidierRLopes/fine-tune-llm/blob/main/scripts/upload_model_to_hf.py\" target=\"_blank\" rel=\"noopener noreferrer\">script upload_model_to_hf.py</a>, I have uploaded the model to <a href=\"https://huggingface.co/didierlopes/phi-3-mini-4k-instruct-ft-on-my-blog\" target=\"_blank\" rel=\"noopener noreferrer\">my Hugging Face repo</a>.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-09-02-fine-tuning-a-llm-on-my-blog-posts_9.webp\"></p>\n<details class=\"details_lb9f alert alert--info details_b_Ee\" data-collapsed=\"true\"><summary>Uploading model to hugging face logs</summary><div><div class=\"collapsibleContent_i85q\"><div class=\"language-bash codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-bash codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">$ python scripts/05_upload_model.py --repo-name didierlopes/phi-3-mini-4k-instruct-ft-on-my-blog</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">============================================================</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">MODEL UPLOAD PIPELINE</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">============================================================</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Model path: models/adapters</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Model type: LoRA Adapters</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Repository: didierlopes/phi-3-mini-4k-instruct-ft-on-my-blog</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Private: False</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Dry run: False</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Step 1: Validating model structure...</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">⚠️  Warning: Missing recommended files: ['config.json']</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">✅ Model validation passed</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Found 21 model weight files</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Total model size: 252.1 MB</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Step 2: Initializing HuggingFace API...</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">✅ Authenticated as: didierlopes</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Step 3: Creating repository...</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">✅ Repository ready: https://huggingface.co/didierlopes/phi-3-mini-4k-instruct-ft-on-my-blog</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Step 4: Creating model card...</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">✅ Model card created: models/adapters/README.md</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Step 5: Uploading model files...</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Uploading 23 files...</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Processing Files (21 / 21)              : 100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████|  264MB /  264MB,  441MB/s  </span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">New Data Upload                         : |                                                                                                                                                                                                                      |  0.00B /  0.00B,  0.00B/s  </span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">...apters/0000800_adapters.safetensors: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 12.6MB / 12.6MB            </span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">...apters/0002000_adapters.safetensors: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 12.6MB / 12.6MB            </span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">...apters/0000500_adapters.safetensors: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 12.6MB / 12.6MB            </span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">...apters/0001900_adapters.safetensors: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 12.6MB / 12.6MB            </span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">...apters/0001500_adapters.safetensors: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 12.6MB / 12.6MB            </span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">...apters/0000600_adapters.safetensors: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 12.6MB / 12.6MB            </span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">...apters/0000700_adapters.safetensors: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 12.6MB / 12.6MB            </span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">...apters/0001000_adapters.safetensors: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 12.6MB / 12.6MB            </span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">...apters/0001100_adapters.safetensors: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 12.6MB / 12.6MB            </span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">...apters/0000900_adapters.safetensors: 100%|██████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 12.6MB / 12.6MB            </span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">No files have been modified since last commit. Skipping to prevent empty commit.</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">✅ Upload completed successfully!</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Step 6: Verifying upload...</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">✅ Upload verified: 24 files in repository</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">============================================================</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">MODEL UPLOAD COMPLETED SUCCESSFULLY!</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">============================================================</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">🎉 Model uploaded to: https://huggingface.co/didierlopes/phi-3-mini-4k-instruct-ft-on-my-blog</span><br></span></code></pre></div></div></div></div></details>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"fused-model\">Fused model<a href=\"https://didierlopes.com/blog/fine-tuning-a-llm-on-my-blog-posts#fused-model\" class=\"hash-link\" aria-label=\"Direct link to Fused model\" title=\"Direct link to Fused model\">​</a></h2>\n<p>Code can be found here: <a href=\"https://github.com/DidierRLopes/fine-tune-llm/blob/main/scripts/04_fuse_and_evaluate.py\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/DidierRLopes/fine-tune-llm/blob/main/scripts/04_fuse_and_evaluate.py</a>.</p>\n<p>While LoRA adapters are excellent for experimentation and sharing, production deployments often benefit from a single, unified model file. This is where fusion comes in.</p>\n<p align=\"center\"><img width=\"400\" src=\"https://didierlopes.com/blog/2025-09-02-fine-tuning-a-llm-on-my-blog-posts_10.webp\"></p>\n<p>Fusion mathematically merges your LoRA adapter weights back into the base model. It is recommended to use the fused model when:</p>\n<ul>\n<li>Deploying to production</li>\n<li>Inference speed is critical</li>\n<li>You want a single model file</li>\n<li>Sharing with users who aren't familiar with LoRA</li>\n</ul>\n<p>It also uses less memory, since you have a single model instead of a model + its adapters.</p>\n<p>However, keeping adapters may still be important, particularly when</p>\n<ul>\n<li>Experimenting with different configurations<!-- -->\n<ul>\n<li>E.g. if you wanted to fine tune based on your blogs</li>\n</ul>\n</li>\n<li>Storage/bandwidth is limited<!-- -->\n<ul>\n<li>This is why I pushed the adapters to HF and not the fused model</li>\n</ul>\n</li>\n<li>You need to swap between multiple fine-tuned versions</li>\n</ul>\n<p>Note: Fusion is a one-way operation. Once fused, you can't extract the adapters back out. Always keep your original adapter files as your \"source of truth\". Think of the fused model as a compiled binary, and your adapters as the source code.</p>\n<details class=\"details_lb9f alert alert--info details_b_Ee\" data-collapsed=\"true\"><summary>Fused model logs</summary><div><div class=\"collapsibleContent_i85q\"><div class=\"language-bash codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-bash codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">$ python scripts/04_fuse_and_evaluate.py </span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">============================================================</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">FUSION AND COMPREHENSIVE EVALUATION PIPELINE</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">============================================================</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">This script: 1) Fuses adapters  2) Evaluates Base + Runtime + Fused</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Base model: microsoft/Phi-3-mini-4k-instruct</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Adapters: models/adapters</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Fused output: models/fused</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Test data: data/processed/test.json</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">============================================================</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">STEP 1: ADAPTER FUSION</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">============================================================</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">✅ Fusion inputs validated successfully</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">============================================================</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">FUSING LORA ADAPTERS</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">============================================================</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Base model: microsoft/Phi-3-mini-4k-instruct</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Adapters: models/adapters</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Output: models/fused</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Command: mlx_lm.fuse --model microsoft/Phi-3-mini-4k-instruct --adapter-path models/adapters --save-path models/fused</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">------------------------------------------------------------</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Loading pretrained model</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Fetching 13 files: 100%|██████████████████████████████████████████████████████████████████████████████████████| 13/13 [00:00&lt;00:00, 15029.20it/s]</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">------------------------------------------------------------</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">✅ Fusion completed successfully!</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Fused model saved to: models/fused</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">============================================================</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">✅ Fusion completed: models/fused</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">============================================================</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">STEP 2: COMPREHENSIVE EVALUATION</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">============================================================</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Evaluating: Base + Runtime LoRA + Fused</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">================================================================================</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">COMPREHENSIVE MODEL COMPARISON</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Base Model vs Runtime LoRA vs Fused Model</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">================================================================================</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">🔸 Step 1: Evaluating Base Model</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">============================================================</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">EVALUATING MODEL: base_model</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">============================================================</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Loading model: microsoft/Phi-3-mini-4k-instruct</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Fetching 13 files: 100%|██████████████████████████████████████████████████████████████████████████████████████| 13/13 [00:00&lt;00:00, 16881.10it/s]</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Model loaded successfully</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Loading test data from: data/processed/test.json</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Extracted 212 test questions</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Generating predictions for 212 questions...</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Generating predictions:   0%| </span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">(...)</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Generating predictions: 100%|██████████████████████████████████████████████████████████████████████████████████| 212/212 [15:08&lt;00:00,  4.29s/it]</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Calculating metrics for 212 samples...</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Calculating word overlap scores...</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">============================================================</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">BASE_MODEL EVALUATION RESULTS</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">============================================================</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">📊 Word Overlap Metrics:</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Mean:    0.1563</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Median:  0.1532</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Std:     0.0468</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Range:   [0.0000, 0.3333]</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">📏 Length Statistics:</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Predictions: 866.8 chars (±154.2)</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">References:  405.8 chars (±186.8)</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">============================================================</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Metrics saved to: logs/evaluation/base_model_evaluation.json</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Evaluation completed! Results saved to: logs/evaluation/base_model_evaluation.json</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">🔸 Step 2: Evaluating Base Model + Runtime LoRA Adapters</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">============================================================</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">EVALUATING MODEL: lora_runtime (Base + LoRA Adapters)</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">============================================================</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Loading base model: microsoft/Phi-3-mini-4k-instruct</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Fetching 13 files: 100%|██████████████████████████████████████████████████████████████████████████████████████| 13/13 [00:00&lt;00:00, 13977.43it/s]</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Loading adapter config: models/adapters/adapter_config.json</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Freezing base model parameters...</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Applying LoRA adapters...</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Loading adapter weights: models/adapters/adapters.safetensors</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">✅ Model with LoRA adapters loaded successfully</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Trainable parameters: 3,145,728 (0.08%)</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Total parameters:     3,824,225,280</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Loading test data from: data/processed/test.json</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Extracted 212 test questions</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Generating predictions for 212 questions...</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Generating predictions:   0%|             </span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">(...)</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Generating predictions: 100%|██████████████████████████████████████████████████████████████████████████████████| 212/212 [07:07&lt;00:00,  2.02s/it]</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Calculating metrics for 212 samples...</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Calculating word overlap scores...</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">============================================================</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">LORA_RUNTIME EVALUATION RESULTS</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">============================================================</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">📊 Word Overlap Metrics:</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Mean:    0.1940</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Median:  0.1847</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Std:     0.0627</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Range:   [0.0658, 0.3846]</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">📏 Length Statistics:</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Predictions: 377.1 chars (±70.4)</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">References:  405.8 chars (±186.8)</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">============================================================</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Metrics saved to: logs/evaluation/lora_runtime_evaluation.json</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Evaluation completed! Results saved to: logs/evaluation/lora_runtime_evaluation.json</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">🔸 Step 3: Evaluating Fused Model</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">============================================================</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">EVALUATING MODEL: lora_fused</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">============================================================</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Loading model: models/fused</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Model loaded successfully</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Loading test data from: data/processed/test.json</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Extracted 212 test questions</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Generating predictions for 212 questions...</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Generating predictions:   0%|  </span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">(...)</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Generating predictions: 100%|██████████████████████████████████████████████████████████████████████████████████| 212/212 [06:23&lt;00:00,  1.81s/it]</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Calculating metrics for 212 samples...</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Calculating word overlap scores...</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">============================================================</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">LORA_FUSED EVALUATION RESULTS</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">============================================================</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">📊 Word Overlap Metrics:</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Mean:    0.2027</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Median:  0.2000</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Std:     0.0638</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Range:   [0.0690, 0.4521]</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">📏 Length Statistics:</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Predictions: 379.1 chars (±61.8)</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">References:  405.8 chars (±186.8)</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">============================================================</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Metrics saved to: logs/evaluation/lora_fused_evaluation.json</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Evaluation completed! Results saved to: logs/evaluation/lora_fused_evaluation.json</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">🔸 Step 4: Model Comparison</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">============================================================</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">MODEL COMPARISON</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">============================================================</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">📊 Model Performance Comparison:</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">------------------------------------------------------------</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Rank   Model                     Score           Metric         </span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">------------------------------------------------------------</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">1      lora_fused                0.2027        Word Overlap</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">2      lora_runtime              0.1940        Word Overlap</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">3      base_model                0.1563        Word Overlap</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">------------------------------------------------------------</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">🎯 Best Model (lora_fused) vs Baseline (base_model):</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Score Improvement: +29.7%</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">base_model: 0.1563</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">lora_fused: 0.2027</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">============================================================</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">🔸 Step 5: Fusion Verification</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">============================================================</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">FUSION QUALITY VERIFICATION</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">============================================================</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">📊 Word Overlap Comparison:</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Runtime Adapters: 0.1940</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Fused Model:      0.2027</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Absolute Diff:    0.0086</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Relative Diff:    4.45%</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">⚠️  Acceptable fusion quality - some degradation detected</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">📈 Additional Metrics Comparison:</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Word Overlap Std Dev: Runtime 0.0627 | Fused 0.0638</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Word Overlap Range:   Runtime [0.066, 0.385] | Fused [0.069, 0.452]</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">============================================================</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">📁 Comprehensive results saved to: logs/evaluation/comprehensive_comparison_20250818_021105.json</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">============================================================</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">PIPELINE COMPLETED SUCCESSFULLY!</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">============================================================</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">📊 Models Evaluated: base_model, lora_runtime, lora_fused</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">🎯 Key Results:</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">base_model: 0.1563 (Word Overlap)</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">lora_runtime: 0.1940 (Word Overlap)</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">lora_fused: 0.2027 (Word Overlap)</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">📁 Detailed results saved to: logs/evaluation/</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">📁 Fused model available at: models/fused</span><br></span></code></pre></div></div></div></div></details>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"wrap-up\">Wrap up<a href=\"https://didierlopes.com/blog/fine-tuning-a-llm-on-my-blog-posts#wrap-up\" class=\"hash-link\" aria-label=\"Direct link to Wrap up\" title=\"Direct link to Wrap up\">​</a></h2>\n<p>And that’s it!</p>\n<p>The results demonstrate that LoRA fine-tuning achieved its goal: meaningful performance improvement with minimal computational overhead, faster inference, and more focused responses that better match the target domain.</p>\n<p>I hope you find this helpful, all the code can be found here: <a href=\"https://github.com/DidierRLopes/fine-tune-llm\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/DidierRLopes/fine-tune-llm</a>.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/fine-tuning-a-llm-on-my-blog-posts",
            "title": "Fine-tuning a LLM on my blog posts",
            "summary": "Ever wondered what it would be like to have an AI that writes exactly in your style? I did. And in this post, I share what I did about it. This is a very practical guide on how to fine-tune an LLM using LoRA with MLX on Apple Silicon.",
            "date_modified": "2025-09-02T00:00:00.000Z",
            "tags": [
                "ai",
                "machine-learning",
                "open-source",
                "tutorial",
                "apple-silicon",
                "llm",
                "fine-tuning"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/top-10-openbb-apps",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-08-25-top-10-openbb-apps.webp\"></p>\n<p>These are my top 10 OpenBB apps, highlighted on our new solutions page. Not slides - literal workflows.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"1-portfolio-performance--exposure\">1. Portfolio Performance &amp; Exposure<a href=\"https://didierlopes.com/blog/top-10-openbb-apps#1-portfolio-performance--exposure\" class=\"hash-link\" aria-label=\"Direct link to 1. Portfolio Performance &amp; Exposure\" title=\"Direct link to 1. Portfolio Performance &amp; Exposure\">​</a></h2>\n<p>I like it because it’s a classic - one of the first strong apps we put together and showed in the FDP presentation. Track overall portfolio performance, returns by asset class, sector exposures, and risk metrics like drawdown or volatility, then generate clean summaries for internal reviews or external stakeholders.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-08-25-top-10-openbb-apps_1.webp\"></p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"2-draft-investor-letter\">2. Draft Investor Letter<a href=\"https://didierlopes.com/blog/top-10-openbb-apps#2-draft-investor-letter\" class=\"hash-link\" aria-label=\"Direct link to 2. Draft Investor Letter\" title=\"Direct link to 2. Draft Investor Letter\">​</a></h2>\n<p>This builds on the portfolio app. It allows firms to automate an investor letter end-to-end by pulling live portfolio data, performance charts, and commentary into a structured, branded format. It cuts manual effort, preserves data integrity, and keeps reporting on time—so the team can focus on the narrative, not the formatting.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-08-25-top-10-openbb-apps_2.webp\"></p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"3-gdp-forecast-trends--cpi-scenarios\">3. GDP Forecast Trends &amp; CPI Scenarios<a href=\"https://didierlopes.com/blog/top-10-openbb-apps#3-gdp-forecast-trends--cpi-scenarios\" class=\"hash-link\" aria-label=\"Direct link to 3. GDP Forecast Trends &amp; CPI Scenarios\" title=\"Direct link to 3. GDP Forecast Trends &amp; CPI Scenarios\">​</a></h2>\n<p>I like it because it’s not just market data - it brings real forecasts and trends into the workflow. As Caique puts it, this dashboard \"makes scenario planning and risk assessment intuitive and data-driven\", so adding new or emerging macro trends is a couple clicks away.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-08-25-top-10-openbb-apps_3.webp\"></p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"4-vector-strength-histogram\">4. Vector Strength Histogram<a href=\"https://didierlopes.com/blog/top-10-openbb-apps#4-vector-strength-histogram\" class=\"hash-link\" aria-label=\"Direct link to 4. Vector Strength Histogram\" title=\"Direct link to 4. Vector Strength Histogram\">​</a></h2>\n<p>I like this one because I hadn’t seen anything like it before - a complex way to score hundreds of support/resistance trajectories by alignment, frequency, and proximity to current price. As the VecViz founder said, OpenBB lets proprietary models live safely next to other apps and Copilot, accelerating idea generation and sharpening risk/opportunity views.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-08-25-top-10-openbb-apps_4.webp\"></p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"5-crypto-research\">5. Crypto Research<a href=\"https://didierlopes.com/blog/top-10-openbb-apps#5-crypto-research\" class=\"hash-link\" aria-label=\"Direct link to 5. Crypto Research\" title=\"Direct link to 5. Crypto Research\">​</a></h2>\n<p>I like this one because it was one of the first apps built by someone external - and it stitched together multiple crypto vendors (CoinGecko, DeFiLlama, Velo Data, and more). It lets you compare tokenomics, developer activity, and on-chain metrics in one place, and as Matt put it: \"OpenBB gives me sophisticated dashboarding and AI tools to pull real insight from the data we buy\".</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-08-25-top-10-openbb-apps_5.webp\"></p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"6-shipping--bunkers-pricing\">6. Shipping &amp; Bunkers Pricing<a href=\"https://didierlopes.com/blog/top-10-openbb-apps#6-shipping--bunkers-pricing\" class=\"hash-link\" aria-label=\"Direct link to 6. Shipping &amp; Bunkers Pricing\" title=\"Direct link to 6. Shipping &amp; Bunkers Pricing\">​</a></h2>\n<p>This was one of our first alternative data feeds into OpenBB, where a client integrated ICE bunker futures pricing and their inbox. Track fuel prices, freight indices, and route-specific congestion to anticipate cost pressures and logistics trends - and correlate these with client requests.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-08-25-top-10-openbb-apps_6.webp\"></p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"7-polymarket-prediction-market\">7. Polymarket Prediction Market<a href=\"https://didierlopes.com/blog/top-10-openbb-apps#7-polymarket-prediction-market\" class=\"hash-link\" aria-label=\"Direct link to 7. Polymarket Prediction Market\" title=\"Direct link to 7. Polymarket Prediction Market\">​</a></h2>\n<p>This quote from Jose, says everything: \"Prediction markets reveal sentiment, but the alpha comes from cross-referencing it with traditional and crypto data. OpenBB Workspace lets me pull Polymarket feeds alongside equity and crypto signals - one dashboard, AI-powered analysis across all three data streams - so scenarios get sharper and workflows get faster\".</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-08-25-top-10-openbb-apps_7.webp\"></p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"8-compliance-intelligence\">8. Compliance Intelligence<a href=\"https://didierlopes.com/blog/top-10-openbb-apps#8-compliance-intelligence\" class=\"hash-link\" aria-label=\"Direct link to 8. Compliance Intelligence\" title=\"Direct link to 8. Compliance Intelligence\">​</a></h2>\n<p>We used the Workspace to navigate SOC2 compliance documentation ourselves. Copilot makes policy docs, audit reports, and vendor packets instantly queryable - pulling the exact page, line, and context - so multi-day reviews compress into focused sprints with far less hunting and far more certainty.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-08-25-top-10-openbb-apps_8.webp\"></p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"9-real-time-feeds\">9. Real-Time Feeds<a href=\"https://didierlopes.com/blog/top-10-openbb-apps#9-real-time-feeds\" class=\"hash-link\" aria-label=\"Direct link to 9. Real-Time Feeds\" title=\"Direct link to 9. Real-Time Feeds\">​</a></h2>\n<p>I like this one particularly because it features real-time feeds from Pyth. Stream live prices and market depth into custom widgets and dashboards, and even embed iframe-able components like TradingView - so traders can build a real-time, decision-ready view inside OpenBB.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-08-25-top-10-openbb-apps_9.webp\"></p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"10-congress-bills-tracking--analysis\">10. Congress Bills Tracking &amp; Analysis<a href=\"https://didierlopes.com/blog/top-10-openbb-apps#10-congress-bills-tracking--analysis\" class=\"hash-link\" aria-label=\"Direct link to 10. Congress Bills Tracking &amp; Analysis\" title=\"Direct link to 10. Congress Bills Tracking &amp; Analysis\">​</a></h2>\n<p>Analyze the newest bills, including the \"Big Beautiful Bill\" with AI out of the box. Visualize legislative momentum across topics, chambers, and progress; assess potential market impact; and, best part, you can actually access the underlying data from the open-source platform alongside official government feeds and legislative APIs.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-08-25-top-10-openbb-apps_10.webp\"></p>\n<p>This data is actually available through our open source platform here: <a href=\"https://github.com/OpenBB-finance/OpenBB\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/OpenBB-finance/OpenBB</a>.</p>\n<hr>\n<p>Many more amazing examples of workflows have been built, and you can find them here: <a href=\"https://openbb.co/solutions\" target=\"_blank\" rel=\"noopener noreferrer\">https://openbb.co/solutions</a>.</p>\n<p>If you need help to get started - reach out 🤝</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/top-10-openbb-apps",
            "title": "Top 10 OpenBB apps",
            "summary": "These are my top 10 OpenBB apps, highlighted on our new solutions page. Not slides - literal workflows.",
            "date_modified": "2025-08-25T00:00:00.000Z",
            "tags": [
                "financial-data",
                "ai",
                "openbb",
                "workflows",
                "apps",
                "solutions"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/can-i-create-a-1-min-ad-on-my-own-with-zero-video-editing-skills",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-08-23-can-i-create-a-1-min-ad-on-my-own-with-zero-video-editing-skills.webp\"></p>\n<p>A hands-on experiment using Google's Veo3 AI to create a professional 1-minute video ad with zero video editing experience. Covers the complete workflow from script writing using the Hero's Journey framework to JSON-structured prompting techniques that unlock better AI video generation results.</p>\n<!-- -->\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>It all started with this Kalshi AI Ad that went viral.</p>\n<div class=\"flex place-items-center justify-center items-center rounded-sm mx-auto\"><iframe src=\"https://www.youtube.com/embed/mzXFURkcCt4?si=TyLHBw1QX8l2KFNA\" width=\"800\" height=\"400\"></iframe></div>\n<br>\n<p>When I saw this AI-generated ad, my thought was: \"<em>Wtf. There’s no way this was solely done using AI.</em>”</p>\n<p>Then I saw a lot of people on X sharing their Veo-3 AI-generated clips, and I was like: “<em>hmmm, maybe it is possible</em>”.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"the-script\">The script<a href=\"https://didierlopes.com/blog/can-i-create-a-1-min-ad-on-my-own-with-zero-video-editing-skills#the-script\" class=\"hash-link\" aria-label=\"Direct link to The script\" title=\"Direct link to The script\">​</a></h2>\n<p>Between dog walks and daily routines, I found myself sketching out ideas for what would become an AI-generated video to announce OpenBB’s position as a counterpoint to legacy workspace infrastructure.</p>\n<p>This would be a cinematic short film about the transformation of financial infrastructure and the rise of OpenBB.</p>\n<p>I iterated on this script on my own in terms of what I wanted for it to happen at a very high level, in order to invoke emotion to the audience - in order to do that, I followed the typical Hero journey framework.</p>\n<p>Here’s a brief description of what I ended up with at a very high level.</p>\n<ul>\n<li>\n<p><strong>The ordinary world</strong>: The legacy financial office with tired analysts in gray suits. Repetitive, robotic work on outdated CRT terminals. This establishes the mundane, oppressive status quo.</p>\n</li>\n<li>\n<p><strong>The call to adventure (opening)</strong>: The young analyst pauses and closes their screen. The moment of questioning: \"What if we started over?\". The frosted-glass door labeled \"UNLOCKED\" literally represents the call.</p>\n</li>\n<li>\n<p><strong>Crossing the threshold (transition)</strong>: Walking through the \"UNLOCKED\" door. The flood of light as they enter the futuristic workspace. It symbolizes leaving the old world behind. Launching OpenBB is the point of no return.</p>\n</li>\n<li>\n<p><strong>Tests and allies</strong>: Other analysts join the journey (allies). Each person transforms into their unique self (rejecting uniformity). The collaborative work represents the tests - learning new ways to work. The AI agent becomes a supernatural aid/mentor figure.</p>\n</li>\n<li>\n<p><strong>The Ordeal (system collapse)</strong>: The legacy system crashes (\"INTERNAL ERROR\"). This is the death/destruction of the old world. The moment of greatest crisis for those still trapped.</p>\n</li>\n<li>\n<p><strong>The revelation/reward (digital dissolution)</strong>: The walls literally dissolve, revealing the truth. The massive Hub represents the reward/treasure. \"This isn't an upgrade. This is a migration\" - the wisdom gained.</p>\n</li>\n<li>\n<p><strong>The return</strong>: The black void and logo emergence. Sharing the message with the world: \"WE DON'T SELL DATA. WE SELL FREEDOM.\". \"The financial industry isn't rebooting\" - bringing this knowledge back to transform society.</p>\n</li>\n</ul>\n<p>Then I had ChatGPT help me decompose this into different scenes.</p>\n<p>Also bear in mind that these AI video models are trained to output 8s videos, so I wanted to try to have each scene not taking longer than that. At least the core of it - as it’s hard to preserve scene styles between 8s clip.</p>\n<p>Although the “extend” feature on Google’s Flow was better than what I hoped for. More on this later.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"flow---veo3\">Flow - Veo3<a href=\"https://didierlopes.com/blog/can-i-create-a-1-min-ad-on-my-own-with-zero-video-editing-skills#flow---veo3\" class=\"hash-link\" aria-label=\"Direct link to Flow - Veo3\" title=\"Direct link to Flow - Veo3\">​</a></h2>\n<p>I first went to Google AI Studio, to the Generate Media section and tried to paste one the scenes text I had.</p>\n<p>Although it was free, the output was pretty disappointing and that’s when I noticed that this was Veo2, and not Veo3 - the model that everyone was raving about on X.</p>\n<p>Then I tried to upgrade to Veo3 - but in the typical Google manner - I couldn’t. Ultimately I found it in Google DeepMind platform which pointed me to try it in Flow.</p>\n<p>I didn’t have the right subscription so I signed up to “Google AI Ultra for Business” which costed $125/mo (with a 50% discount). The estimates is that this provides around 1250 clips, which is enough, because the quality of the model is extremely impressive and there are ways to squeeze performance out of it - through prompt engineering.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-08-23-can-i-create-a-1-min-ad-on-my-own-with-zero-video-editing-skills_1.webp\"></p>\n<p>Copy-pasting the scenes as I had them on a document produced very impressive results, but I felt like the results were very diverse among each run.</p>\n<p>I felt like it needed more structure. Then I saw several creators mentioned that these models performed significantly better with JSON-structured inputs rather than simple text prompts.</p>\n<p>So I copied the text narrative of each of the scenes and converted these into JSON.</p>\n<p><strong>Example:</strong></p>\n<div class=\"language-json codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-json codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">{</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">  </span><span class=\"token property\">\"scene and action\"</span><span class=\"token operator\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"A slow dolly shot glides across a rigid financial office. Identical gray cubicles house analysts in matching suits, typing robotically at CRT-style terminals with pixelated dashboards. Close-ups reveal tired faces, blinking cursors, and a mechanical monotony. Voiceover: 'For decades, the tools of finance have remained the same. Expensive. Opaque. Inflexible. You weren’t meant to build with them. You were meant to follow.'\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">  </span><span class=\"token property\">\"camera angle\"</span><span class=\"token operator\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"center-aligned symmetry with slow dolly pans\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">  </span><span class=\"token property\">\"lighting\"</span><span class=\"token operator\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"harsh fluorescent with blue-gray tint\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">  </span><span class=\"token property\">\"room\"</span><span class=\"token operator\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"legacy financial office\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">  </span><span class=\"token property\">\"ratio\"</span><span class=\"token operator\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"16:9\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">  </span><span class=\"token property\">\"character\"</span><span class=\"token operator\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"analysts in identical gray suits, robotic behavior\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">  </span><span class=\"token property\">\"voice\"</span><span class=\"token operator\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"calm and authoritative male voice\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">  </span><span class=\"token property\">\"furniture\"</span><span class=\"token operator\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">[</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"CRT monitors\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"repetitive gray cubicles\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"fluorescent ceiling lights\"</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">  </span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">]</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">  </span><span class=\"token property\">\"action and motion\"</span><span class=\"token operator\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"minimal movement, robotic typing, blinking screens, fluorescent flickering\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">  </span><span class=\"token property\">\"keywords\"</span><span class=\"token operator\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">[</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"legacy finance\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"monotony\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"rigid systems\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"pixelated UI\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"inflexibility\"</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">  </span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">]</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">}</span><br></span></code></pre></div></div>\n<p>This level of detail gave us precise control over every aspect of the scene, and then we just had to paste it to Flow and let the model cook 🧑‍🍳.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-08-23-can-i-create-a-1-min-ad-on-my-own-with-zero-video-editing-skills_2.webp\"></p>\n<p>That improved the quality and reproducibility significantly.</p>\n<p>But I knew we could still get more out of it so I iterated on these prompts with ChatGPT so it would add more relevant keys: value pairs to this JSON, such as:</p>\n<ul>\n<li>Scene and action descriptions</li>\n<li>Camera angles and movement</li>\n<li>Lighting and color grading</li>\n<li>Character direction and emotion</li>\n<li>Environmental details</li>\n<li>Keywords for style consistency</li>\n</ul>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-08-23-can-i-create-a-1-min-ad-on-my-own-with-zero-video-editing-skills_3.webp\"></p>\n<p>This JSON structure forced me to think about every element, which was awesome.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"iteration\">Iteration<a href=\"https://didierlopes.com/blog/can-i-create-a-1-min-ad-on-my-own-with-zero-video-editing-skills#iteration\" class=\"hash-link\" aria-label=\"Direct link to Iteration\" title=\"Direct link to Iteration\">​</a></h2>\n<p>At this point I knew there was something here.</p>\n<p><strong>I was - once again - mind blown by AI and what it could enable.</strong></p>\n<p>There I was, never having done any video editing/film concept - being able to do something on my own in very very little time.</p>\n<p>This is the point at which I asked help.</p>\n<p>While I was good at the technical prompt crafting, my wife has an eye for what actually looks good on screen and so she did all the iteration after that initial work. Flow's feature allowing 4 variations per prompt was a game-changer here,  instead of generating one video and hoping for the best, she could compare options and identify what worked.</p>\n<p>But also the Extend feature of flow which allows a scene to be based on the past ones so characters/environments aren’t lost between clips. Particularly relevant as we wanted to follow the Hero journey and for that the audience needs to develop a relationship/affinity with the hero.</p>\n<p>Then our marketing, Rita, helped refine the copy to make it perfect- with OpenBB style all over it.</p>\n<p>And then my wife just helped stitching things together and having audio being synced with the video.</p>\n<p>To the final result, which you can see here:</p>\n<div class=\"flex place-items-center justify-center items-center rounded-sm mx-auto\"><iframe src=\"https://www.youtube.com/embed/FWL0A3BdgcI?si=BqyWvMjFYJTA0uOq\" width=\"800\" height=\"400\"></iframe></div>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"final-thoughts\">Final thoughts<a href=\"https://didierlopes.com/blog/can-i-create-a-1-min-ad-on-my-own-with-zero-video-editing-skills#final-thoughts\" class=\"hash-link\" aria-label=\"Direct link to Final thoughts\" title=\"Direct link to Final thoughts\">​</a></h2>\n<p>What started as a weekend curiosity turned into a legitimate short film.</p>\n<p>The tools are there, the quality is impressive, and the barrier to entry is lower than ever.</p>\n<p>But perhaps most importantly, AI video generation doesn't replace human creativity – it amplifies it.</p>\n<p>This represents more than just a technical experiment.</p>\n<p>It's LITERAL proof that individual creators can now produce content that would have required significant budgets and teams just a few years ago.</p>\n<p>We are definitely in a golden age. Enjoy.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/can-i-create-a-1-min-ad-on-my-own-with-zero-video-editing-skills",
            "title": "Can I create a 1 min Ad on my own with zero video editing skills?",
            "summary": "A hands-on experiment using Google's Veo3 AI to create a professional 1-minute video ad with zero video editing experience. Covers the complete workflow from script writing using the Hero's Journey framework to JSON-structured prompting techniques that unlock better AI video generation results.",
            "date_modified": "2025-08-23T00:00:00.000Z",
            "tags": [
                "ai-tools",
                "video-generation",
                "content-creation",
                "marketing",
                "veo3",
                "prompt-engineering",
                "startup",
                "openbb"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/using-claude-code-in-god-mode",
            "content_html": "<p>Learn how to squeeze performance out of Claude Code.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>Brief demo of how I use Claude Code.</p>\n<div class=\"flex place-items-center justify-center items-center rounded-sm mx-auto\"><iframe src=\"https://www.youtube.com/embed/E9Q6le-ahaA?si=bUizX39byP5NpFLy\" width=\"800\" height=\"400\"></iframe></div>\n<br>\n<p>Below you will find the step-by-step guide on how to get here.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"get-started-with-claude-code\">Get started with Claude Code<a href=\"https://didierlopes.com/blog/using-claude-code-in-god-mode#get-started-with-claude-code\" class=\"hash-link\" aria-label=\"Direct link to Get started with Claude Code\" title=\"Direct link to Get started with Claude Code\">​</a></h2>\n<p>Install Claude Code.</p>\n<div class=\"language-text codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-text codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">npm install -g @anthropic-ai/claude-code</span><br></span></code></pre></div></div>\n<p>Then run claude in your project of choice:</p>\n<div class=\"language-text codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-text codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">claude</span><br></span></code></pre></div></div>\n<p>It’s that easy. (documentation <a href=\"https://docs.anthropic.com/en/docs/claude-code/setup\" target=\"_blank\">here</a>)</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"a-set-up-claudemd\">A. Set up CLAUDE.md<a href=\"https://didierlopes.com/blog/using-claude-code-in-god-mode#a-set-up-claudemd\" class=\"hash-link\" aria-label=\"Direct link to A. Set up CLAUDE.md\" title=\"Direct link to A. Set up CLAUDE.md\">​</a></h2>\n<ol>\n<li>Go to the project of interest, and run claude in the terminal there.</li>\n</ol>\n<br>\n<p>When it is open, run:</p>\n<div class=\"language-text codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-text codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">init</span><br></span></code></pre></div></div>\n<p>Claude will then analyze your codebase in that folder and create a <code>CLAUDE.md</code> file that Claude will take into account every time you are working with it.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-08-16-using-claude-code-in-god-mode_1.webp\"></p>\n<ol start=\"2\">\n<li>Tweak CLAUDE.md to fit your needs.</li>\n</ol>\n<br>\n<p>Here’s my recommendation - leave CLAUDE.md as is at the start. As you get more familiar with claude you will understand what you like, but <strong>more importantly</strong>, what you dislike about it.</p>\n<p>Here’s where I landed with \"my\" preferences. (Open source repo <a href=\"https://github.com/DidierRLopes/CLAUDE.md/blob/main/README.md\" target=\"_blank\">here</a>)</p>\n<div class=\"language-text codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-text codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">## 1. Global scope &amp; boundaries</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">- NEVER run any linters unless explicitly asked.</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">- NEVER write unit tests unless explicitly asked.</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">- NEVER refactor code that is outside the scope of the request.</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">- NEVER run the build; I will run it locally.</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">## 2. Alignment before starting</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">- Restate my goal in your own words.</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">- List unknowns and ask clarifying questions until the request is unambiguous.</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">- Wait for my confirmation before proceeding.</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">## 3. Implementation Planning</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">### 3.1 Plan of attack</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">- Create a step-by-step plan with small, verifiable commits.</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">- Include a rollback plan.</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">- Wait for my go-ahead before writing code.</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">### 3.2 Change surface</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">- List all files you expect to modify.</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">- If you are going to add 1 or more new files ask me permission to do so and explain what is the purpose of each of the files created. And why you couldn't use the others available.</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">- If you are going to delete 1 or more files ask me permission to do so and tell me what the file used to do and why you want to get rid of it.</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">### 3.3 Edge cases list</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">- Enumerate edge cases, failure modes, and concurrency/race concerns.</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">- State how each will be handled.</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">### 3.4 Testing strategy</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">- Assume I will run tests/builds. Do not run the build.</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">- Add lightweight debug hooks (console.log or equivalent) at key points so I can verify behavior quickly.</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">- Outline what to test and expected outputs, but only include actual tests if I explicitly ask.</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">### 3.5 Reuse before rebuild</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">- Identify existing utilities/hooks/services to reuse.</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">- If introducing a new abstraction, justify why reuse isn’t sufficient.</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">### 3.6 MVP first (divide to conquer)</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">- Propose a simplistic first pass to validate direction (minimal interface, happy path).</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">- Plan the follow-up phases to complete the full implementation after MVP is confirmed.</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">## 4. Step phased plan (detailed prompt)</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Use the agreed Design/PRD, that we iterated together, as the single source of truth. Before coding, produce a 5–8 step phased plan. Each phase specifies goals, files to touch, and, when helpful, tiny code diffs/pseudocode (&lt;15 lines). Keep phases minimal, shippable, and verifiable.</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Deliverables before coding:</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">- a. Goal restatement &amp; acceptance criteria.</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">- b. Repo scan &amp; reuse targets.</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">- c. Implementation plan (5–8 phases) with file changes and small diffs.</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">- d. Testing strategy with debug logs I can use.</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">- e. Risks &amp; rollback.</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">- f. Clarifying questions if any ambiguity remains.</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">## 5. Code Style &amp; Comments</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">- Avoid line-by-line comments.</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">- Comment only where logic is non-obvious.</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">## 6. During Execution</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">- If blocked or uncertain, stop and present 2–3 options with pros/cons; confirm before proceeding.</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">- Stick to the plan and scope; confirm any scope expansion first.</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">- Keep diffs small and mapped to phases; include the debug logs defined in 3.4.</span><br></span></code></pre></div></div>\n<p>One of the reasons for which it’s important to have such an extensive/detailed prompt is that is VERY easy (I cannot emphasis this enough) to get stuck in a loop.</p>\n<p>The amount of times I had to <code>git restore</code> or <code>git stash</code> and start from scratch is mind blowing. And it happened every single time when I was being too optimistic about Claude being able to one-shot a feature.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-08-16-using-claude-code-in-god-mode_2.webp\"></p>\n<p>Like this lol</p>\n<p>The problem with these is that you get a false sense of progress, but you just start digging more and more. And at some point you will realize that you are better to start off from the start. At that time you are maybe like 5/6 prompts in with 8 files modified and a LOT of tokens that went to waste.</p>\n<p>A better prompt will not only save you the tokens, but save you the time. It’s worth editing to reflect your goals.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"b-add-notifications-for-when-claude-code-finishes\">B. Add notifications for when Claude Code finishes<a href=\"https://didierlopes.com/blog/using-claude-code-in-god-mode#b-add-notifications-for-when-claude-code-finishes\" class=\"hash-link\" aria-label=\"Direct link to B. Add notifications for when Claude Code finishes\" title=\"Direct link to B. Add notifications for when Claude Code finishes\">​</a></h2>\n<ol>\n<li>Create a notifier script. Open the Terminal and run:</li>\n</ol>\n<br>\n<div class=\"language-text codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-text codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">mkdir -p ~/.claude/scripts</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">cat &gt; ~/.claude/scripts/notify-end.sh &lt;&lt;'SH'</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">#!/usr/bin/env bash</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\"># Minimal, dependency-free notification</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\"># Shows a macOS banner + plays a short sound.</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">TITLE=\"Claude Code\"</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">MESSAGE=\"Task complete\"</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\"># macOS banner with sound</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">osascript -e \"display notification \\\"$MESSAGE\\\" with title \\\"$TITLE\\\" sound name \\\"Glass\\\"\"</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\"># Extra: play sound explicitly in case banners are muted</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">afplay /System/Library/Sounds/Glass.aiff &gt;/dev/null 2&gt;&amp;1 &amp;</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">SH</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">chmod +x ~/.claude/scripts/notify-end.sh</span><br></span></code></pre></div></div>\n<ol start=\"2\">\n<li>Add a global Claude Code global config. Run this in the terminal:</li>\n</ol>\n<br>\n<div class=\"language-text codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-text codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">mkdir -p ~/.claude</span><br></span></code></pre></div></div>\n<ol start=\"3\">\n<li>Add the Stop hook in Claude Code’s CLI config - <code>~/.claude/settings.json</code>.</li>\n</ol>\n<p>Create this minimal file or edit the existing one by merging the \"hooks\" block correctly:</p>\n<div class=\"language-json codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-json codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">{</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">  </span><span class=\"token property\">\"hooks\"</span><span class=\"token operator\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">{</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    </span><span class=\"token property\">\"Stop\"</span><span class=\"token operator\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">[</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">      </span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">{</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">        </span><span class=\"token property\">\"matcher\"</span><span class=\"token operator\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">        </span><span class=\"token property\">\"hooks\"</span><span class=\"token operator\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">[</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">          </span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">{</span><span class=\"token plain\"> </span><span class=\"token property\">\"type\"</span><span class=\"token operator\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"command\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> </span><span class=\"token property\">\"command\"</span><span class=\"token operator\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"bash ~/.claude/scripts/notify-end.sh\"</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">}</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">        </span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">]</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">      </span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">}</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">]</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">  </span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">}</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">}</span><br></span></code></pre></div></div>\n<ol start=\"4\">\n<li>Test that it works on the terminal.</li>\n</ol>\n<br>\n<div class=\"language-text codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-text codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">bash ~/.claude/scripts/notify-end.sh</span><br></span></code></pre></div></div>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"c-tips--tricks\">C. Tips &amp; Tricks<a href=\"https://didierlopes.com/blog/using-claude-code-in-god-mode#c-tips--tricks\" class=\"hash-link\" aria-label=\"Direct link to C. Tips &amp; Tricks\" title=\"Direct link to C. Tips &amp; Tricks\">​</a></h2>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"compact-mode-sucks\">Compact mode sucks<a href=\"https://didierlopes.com/blog/using-claude-code-in-god-mode#compact-mode-sucks\" class=\"hash-link\" aria-label=\"Direct link to Compact mode sucks\" title=\"Direct link to Compact mode sucks\">​</a></h3>\n<p>My experience with /compact is not great at all. The performance drops drastically when that occurs.</p>\n<p>Claude code displays: <em>“Context left until auto-compact: n%”</em></p>\n<p>My suggestion is that when that number is 10% or less, you ask for Claude to give you a summary of everything that happened up until that point and what are the next steps, without doing any code change.</p>\n<p>Then you can copy that. Close that CC window. Open a new CC and paste that.</p>\n<p>This allows you to be able to edit the content and have more control over what compact is doing under the hood.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"mcp-server\">MCP Server<a href=\"https://didierlopes.com/blog/using-claude-code-in-god-mode#mcp-server\" class=\"hash-link\" aria-label=\"Direct link to MCP Server\" title=\"Direct link to MCP Server\">​</a></h3>\n<p>Don’t be scared to add MCP Servers that make your life easier.</p>\n<p>It’s extremely easy to add an MCP Server - it just depends on where the context you want to enhance CC is. Most of the times I just copy-paste the text from either Confluence, a Slack conversation or I drop a voice note (more on this in a second).</p>\n<p>But sometimes having an MCP Server can make your life easier, as it enables you to do things where copy-pasting isn’t really an option.</p>\n<p>E.g. my favorite is Figma MCP Server - I wrote a post about it <a href=\"https://didierlopes.com/blog/2025-06-10-how-i-connected-figma-to-cursor-using-mcp/\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>. But you can also use browser-tool or puppeteer to have access to the browser and iterate more autonomously.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"annoying-00-and-01-copy-paste-bug\">Annoying 00~ and 01~ copy paste bug<a href=\"https://didierlopes.com/blog/using-claude-code-in-god-mode#annoying-00-and-01-copy-paste-bug\" class=\"hash-link\" aria-label=\"Direct link to Annoying 00~ and 01~ copy paste bug\" title=\"Direct link to Annoying 00~ and 01~ copy paste bug\">​</a></h3>\n<p>There’s a <a href=\"https://github.com/anthropics/claude-code/issues/3134\" target=\"_blank\" rel=\"noopener noreferrer\">known bug</a> when launching and exiting Claude Code, it corrupts terminal paste functionality. All subsequent paste operations are prefixed with 00~ and suffixed with 01~. Like this:</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-08-16-using-claude-code-in-god-mode_3.webp\"></p>\n<p>I usually just type type <code>reset</code> in the terminal and that fixes it.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"d-speech-to-text\">D. Speech-to-text<a href=\"https://didierlopes.com/blog/using-claude-code-in-god-mode#d-speech-to-text\" class=\"hash-link\" aria-label=\"Direct link to D. Speech-to-text\" title=\"Direct link to D. Speech-to-text\">​</a></h2>\n<p>This is a crazy unlock. We are so much faster at speaking than typing.</p>\n<p>To be faster at typing than speaking, you generally need to type around 150 words per minute (WPM) or faster. To put this into perspective, an average person types around 40 WPM, and an experienced programmer between 50-75 WPM.</p>\n<p>My speed is usually just above 100 WPM (you can test your speed here: <a href=\"https://10fastfingers.com/typing-test/english\" target=\"_blank\" rel=\"noopener noreferrer\">https://10fastfingers.com/typing-test/english</a>).</p>\n<p>So what I did was enable dictation on Macbook, and set the shortcut for it to be pressing control key twice (and then control once to stop).</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-08-16-using-claude-code-in-god-mode_4.webp\"></p>\n<p>And it’s awesome - it allows me to dump a bunch of information extremely fast.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"appendix\">Appendix<a href=\"https://didierlopes.com/blog/using-claude-code-in-god-mode#appendix\" class=\"hash-link\" aria-label=\"Direct link to Appendix\" title=\"Direct link to Appendix\">​</a></h2>\n<p>While this allows me to be productive, it also gets the team to start petitions like this 🤣</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-08-16-using-claude-code-in-god-mode_5.webp\"></p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/using-claude-code-in-god-mode",
            "title": "Using Claude Code in God Mode",
            "summary": "Learn how to squeeze performance out of Claude Code.",
            "date_modified": "2025-08-16T00:00:00.000Z",
            "tags": [
                "claude-code",
                "anthropic",
                "dictation",
                "ai",
                "coding"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/openbb-workspace-mcp-the-platform-play-i-cant-stop-thinking-about",
            "content_html": "<p>How a simple protocol could change the way firms build, integrate, and scale with OpenBB.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>When I first heard about the Model Context Protocol (MCP), I didn't get the hype.</p>\n<p>People on X were starting to buzz about it - but people hype everything that comes along, and most of those topics fade quickly.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-08-12-openbb-workspace-mcp-the-platform-play-i-cant-stop-thinking-about_1.webp\"></p>\n<p>I kind of understood the idea, but I couldn't see what made it so special from an OpenAPI spec for LLMs.</p>\n<p>At the start of the year, I attended the AI Engineering Conference, where they had a workshop Saturday on MCP by Anthropic, that I attended with <a href=\"https://x.com/virattt\" target=\"_blank\">Virat</a>.</p>\n<div class=\"flex place-items-center justify-center items-center rounded-sm mx-auto\"><iframe src=\"https://www.youtube.com/embed/kQmXtrmQ5Zg?si=BSIRbU3hpB3jCzeH\" width=\"600\" height=\"300\"></iframe></div>\n<br>\n<p>Even then I didn't fully get it.</p>\n<p>Virat, though, got it instantly. A few weeks later, he'd already built an <a href=\"https://docs.financialdatasets.ai/mcp-server\" target=\"_blank\">MCP server for financial datasets</a> - one of the very first for finance.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"wed-been-doing-mcp-all-along\">We'd been doing \"MCP\" all along<a href=\"https://didierlopes.com/blog/openbb-workspace-mcp-the-platform-play-i-cant-stop-thinking-about#wed-been-doing-mcp-all-along\" class=\"hash-link\" aria-label=\"Direct link to We'd been doing &quot;MCP&quot; all along\" title=\"Direct link to We'd been doing &quot;MCP&quot; all along\">​</a></h2>\n<p>Part of my early skepticism was because, in many ways, OpenBB had already solved this problem before MCP even had a name.</p>\n<p>We'd built our own protocol to integrate data into the Workspace so that it could be consumed by both humans (through visualization) and AI agents (through function calls). I even wrote about it <a href=\"https://didierlopes.com/blog/2025-03-01-how-function-calling-and-context-aware-ai-shapes-openbb\" target=\"_blank\">here</a>.</p>\n<p>We spent years making sure that any data feeding the Workspace was equally usable for the UI and for AI - effectively building MCP before MCP existed.</p>\n<p>So when MCP came along, I didn't feel the pull. We already had our own seamless protocol and didn't see why we needed someone else's.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"the-aha-moment-tools-without-a-ui\">The \"Aha\" moment: Tools without a UI<a href=\"https://didierlopes.com/blog/openbb-workspace-mcp-the-platform-play-i-cant-stop-thinking-about#the-aha-moment-tools-without-a-ui\" class=\"hash-link\" aria-label=\"Direct link to The &quot;Aha&quot; moment: Tools without a UI\" title=\"Direct link to The &quot;Aha&quot; moment: Tools without a UI\">​</a></h2>\n<p>Then things started to change.</p>\n<p>MCP topic started showing up on our client conversations. They weren't necessarily asking for MCP at first, but wanted to know what was our strategy towards it.</p>\n<p>At the same time, I was adding MCP Servers to my Claude Code, <a href=\"https://didierlopes.com/blog/2025-06-10-how-i-connected-figma-to-cursor-using-mcp\" target=\"_blank\">such as the Figma one</a>. And that's when my perspective started to shift. There I was with all my data in Figma, and with a couple of clicks my agent in a completely different environment (the terminal) had access to it.</p>\n<p>It wasn't even just about the data but the tools. Ultimately, the context.</p>\n<p>That was it.</p>\n<p>The killer use case for OpenBB wasn't on the data side - we already handle that well with UI components.</p>\n<p>It's <strong>tools that don't need to be visualized</strong>, and can work with the data already in the Workspace.</p>\n<p>Think:</p>\n<ul>\n<li>Writing an investment memo in OpenBB and sending it straight to Ghost (workflow suggested by <a href=\"https://www.linkedin.com/in/ca%C3%ADque-cober-117bbb1ab/\" target=\"_blank\">Caique</a>).</li>\n<li>Using a memory server to remember user preferences across sessions.</li>\n<li>Monte Carlo models</li>\n<li>Code interpreter</li>\n<li>Web search</li>\n<li>…</li>\n</ul>\n<p>It's like a <strong>universal adapter</strong> for capabilities.</p>\n<p>Plug in the tool, and it just works inside the Workspace - for both humans and AI.</p>\n<p>And it's not just a handful of companies working on this.</p>\n<p>There are thousands nows.</p>\n<p>It's the differentiator between companies that innovate and the ones who don't (but will soon do).</p>\n<p>There are full-blown directories with MCP Server URLs that you can connect with a couple of clicks - e.g. smithery.ai with hundreds of MCP servers ready to connect (Derek has an <a href=\"https://youtu.be/ITRvaLmVAWM?si=jprbfEtMGeYU4hMO&amp;t=241\" target=\"_blank\">awesome demo</a> on the topic).</p>\n<p>Each server is a potential new feature.</p>\n<ul>\n<li>\n<p><strong>Before</strong>: every integration was a full-blown project.</p>\n</li>\n<li>\n<p><strong>Now</strong>: browse, connect, use. That easy.</p>\n</li>\n</ul>\n<p>Even simple tools, like <a href=\"https://context7.com/\" target=\"_blank\">Context7</a>, can improve the user experience significantly.</p>\n<p align=\"center\"><img width=\"800\" src=\"https://didierlopes.com/blog/2025-08-12-openbb-workspace-mcp-the-platform-play-i-cant-stop-thinking-about_2.webp\"></p>\n<p>That's when it became obvious - this wasn't just a nice-to-have, it was a platform play.</p>\n<p>Our platform play.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"how-we-decide-what-to-build-ourselves\">How we decide what to build ourselves<a href=\"https://didierlopes.com/blog/openbb-workspace-mcp-the-platform-play-i-cant-stop-thinking-about#how-we-decide-what-to-build-ourselves\" class=\"hash-link\" aria-label=\"Direct link to How we decide what to build ourselves\" title=\"Direct link to How we decide what to build ourselves\">​</a></h2>\n<p>MCP won't replace what we build - it complements it.</p>\n<p>Obviously, when the data is meant to be rendered as a widget on OpenBB - we rely on our protocol. As the information in the protocol contains now just raw data but the way it's displayed on the workspace, the parameters, the apps, the prompts, …</p>\n<p>However, when features relate mostly with the usage of an AI agent we will be more mindful about the features that we want to own.</p>\n<p align=\"center\"><img width=\"800\" src=\"https://didierlopes.com/blog/2025-08-12-openbb-workspace-mcp-the-platform-play-i-cant-stop-thinking-about_3.webp\"></p>\n<p>I foresee us owning the features when:</p>\n<p><strong>They rely deeply on Workspace data, e.g.</strong>:</p>\n<ul>\n<li><strong>Global Data</strong> which gives the agent access to the full range of data widgets in the entire workspace product.</li>\n<li><strong>Generative UI</strong> which gives the agent access to the workspace dashboard and allows to add widgets into the dashboard based on the conversation or modify the dashboard</li>\n</ul>\n<p><strong>We need to control the full end-to-end experience, e.g.</strong>:</p>\n<ul>\n<li><strong>Web Search</strong> where we want to be able to control the way the citations are highlighted so they work more natively on the product</li>\n<li><strong>Code Interpreter</strong> (coming soon) so that we optimize this virtual sandbox to create charts that can be created as interactive widgets to add to the workspace.</li>\n</ul>\n<p>Everything else?</p>\n<p>The MCP ecosystem can handle it - often better than we could build it ourselves.</p>\n<p>And even for some of these, users may still want to add their own web search or code interpreter.</p>\n<p>But ultimately, we are giving them that option.</p>\n<p>The way I see it, MCP turns OpenBB into the place to build financial applications - a permissioned, AI-ready infrastructure layer that can tap into an entire universe of tools without friction.</p>\n<p>A few months ago, I didn't see it.</p>\n<p>Now, I can't stop thinking about what we'll build next.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/openbb-workspace-mcp-the-platform-play-i-cant-stop-thinking-about",
            "title": "OpenBB Workspace + MCP - The platform play I can’t stop thinking about",
            "summary": "How a simple protocol could change the way firms build, integrate, and scale with OpenBB.",
            "date_modified": "2025-08-12T00:00:00.000Z",
            "tags": [
                "openbb",
                "mcp",
                "model-context-protocol",
                "platform-strategy",
                "ai-agents",
                "workspace",
                "integrations",
                "developer-tools",
                "fintech",
                "ai-infrastructure"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/what-if-you-could-access-an-openbb-widget-on-excel",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-08-05-what-if-you-could-access-an-openbb-widget-on-excel.webp\"></p>\n<p>This post introduces a new integration that allows users to embed dynamic OpenBB widgets directly into Excel.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>Some time ago I was asked if I thought Excel was going to survive.</p>\n<p>My answer was: “<strong>I wouldn’t bet against it</strong>”.</p>\n<p>Better than rowing against the tide is positioning yourself to be carried by it.</p>\n<p>We want OpenBB to sit at the core of an organization.</p>\n<p>Be what happens after the data team has been in charge.</p>\n<p>And that means we need to meet users where they are i.e., <strong>allow them to access their analytics &amp; insights from the OpenBB workspace in Excel</strong>.</p>\n<p>After adding an App to OpenBB, you can create a dashboard to fit your exact needs.</p>\n<p>A specific widget may look like this:</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-08-05-what-if-you-could-access-an-openbb-widget-on-excel_1.webp\"></p>\n<p>Where in red you have the parameters that can be modified on the frontend, and in green you have the data associated with it.</p>\n<p>Now, we've had an Excel Add-in for some time that allows users to retrieve data from OpenBB - what it did was basically route the request to our Excel Add-in.</p>\n<p>So you could do something like this:</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-08-05-what-if-you-could-access-an-openbb-widget-on-excel_2.webp\"></p>\n<p>This is great!</p>\n<p><strong>BUT</strong>.</p>\n<p><strong>What if we could do more?</strong></p>\n<p>What if we could bring the concept of a \"Widget\" to Excel?</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"openbb-widget-on-excel\">OpenBB Widget on Excel<a href=\"https://didierlopes.com/blog/what-if-you-could-access-an-openbb-widget-on-excel#openbb-widget-on-excel\" class=\"hash-link\" aria-label=\"Direct link to OpenBB Widget on Excel\" title=\"Direct link to OpenBB Widget on Excel\">​</a></h2>\n<p>I started toying with this idea on an evening, and later that night I shared a POC with the team.</p>\n<p>Raw &amp; unfiltered video below:</p>\n<div class=\"flex place-items-center justify-center items-center rounded-sm mx-auto\"><iframe src=\"https://www.youtube.com/embed/XNAVGyiYT8s?si=RPEe3VIkMbYYtd8g\" width=\"800\" height=\"400\"></iframe></div>\n<br>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"implicit-vs-explicit\">Implicit vs Explicit<a href=\"https://didierlopes.com/blog/what-if-you-could-access-an-openbb-widget-on-excel#implicit-vs-explicit\" class=\"hash-link\" aria-label=\"Direct link to Implicit vs Explicit\" title=\"Direct link to Implicit vs Explicit\">​</a></h3>\n<p>Here’s what the POC entailed in a nutshell:</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-08-05-what-if-you-could-access-an-openbb-widget-on-excel_3.webp\"></p>\n<p>I created a distinction between \"<strong>implicit</strong>\" and \"<strong>explicit</strong>\".</p>\n<p>\"<strong>Implicit</strong>\" is what I shared at the start of this post, where the parameters are in the formula. This is great, but for someone who just copy-pastes the formula, they don’t have visibility into which parameters are actually returning the data they're looking at.</p>\n<p>This is where the \"<strong>explicit</strong>\" concept comes in, mimicking an OpenBB widget.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-08-05-what-if-you-could-access-an-openbb-widget-on-excel_4.webp\"></p>\n<p>So, when you copy-paste into Excel, this is what you get out-of-the-box.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-08-05-what-if-you-could-access-an-openbb-widget-on-excel_5.webp\"></p>\n<p>Notice the analogy with an OpenBB widget, users can modify parameters and have the latest data fetched automatically. All achieved programmatically.</p>\n<p><strong>But we didn’t stop here</strong>.</p>\n<p>The next question we asked ourselves was - if a user wants to visualize a particular OpenBB widget on Excel, why wouldn’t they be interested in visualizing an OpenBB App?</p>\n<p>So, we made it possible for a user to export a dashboard to Excel in 3 formats:</p>\n<ul>\n<li><strong>Static</strong> - where the data is what is available, your typical exporting</li>\n<li><strong>Dynamic</strong> - where it relies on the Excel Add-in for the formula<!-- -->\n<ul>\n<li><strong>Implicit</strong> - with parameters within the formula</li>\n<li><strong>Explicit</strong> - with parameters in the cells above</li>\n</ul>\n</li>\n</ul>\n<p>I’m genuinely excited about this one.</p>\n<p>If this sounds like something your firm would be interested in, feel free to reach out.</p>\n<p>With the platform’s integration with data sources like FRED, BLS, IMF, and more, there’s a lot of data that could be available in Excel out of the box. More on this coming soon.</p>\n<p>A few weeks later I added a Polymarket app to OpenBB and then showed that I had immediate access to it on Excel, check it out below:</p>\n<div class=\"flex place-items-center justify-center items-center rounded-sm mx-auto\"><iframe src=\"https://www.youtube.com/embed/Wfjpwgglw40?si=eo-Ll4nNrxIoGH7L\" width=\"800\" height=\"400\"></iframe></div>\n<br>\n<p>Any feedback let me know!</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/what-if-you-could-access-an-openbb-widget-on-excel",
            "title": "What if... you could access an OpenBB widget on Excel?",
            "summary": "This post introduces a new integration that allows users to embed dynamic OpenBB widgets directly into Excel.",
            "date_modified": "2025-08-05T00:00:00.000Z",
            "tags": [
                "openbb",
                "excel",
                "integration",
                "data-analytics",
                "investment-research",
                "fintech"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/are-you-team-mcp-client-or-server",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-07-29-are-you-team-mcp-client-or-server.webp\"></p>\n<p>The Model Context Protocol (MCP) forces a strategic choice on financial services companies - become a Client, building AI user experiences, or a Server, providing specialized data and tools. This post explores the implications of this divide.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>The Model Context Protocol (MCP) is forcing financial services companies to make a fundamental strategic choice that will define their future in this AI-first world:</p>\n<p><strong>Are you building the stage or performing on it?</strong></p>\n<p>As MCP adoption accelerates across the industry, we're witnessing a critical bifurcation. Companies must decide whether they're going to be an MCP Client or an MCP Server, and this decision will fundamentally shape their business model, competitive positioning, and path to market dominance.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"the-great-divide-mcp-client-vs-mcp-server\">The great divide: MCP Client vs MCP Server<a href=\"https://didierlopes.com/blog/are-you-team-mcp-client-or-server#the-great-divide-mcp-client-vs-mcp-server\" class=\"hash-link\" aria-label=\"Direct link to The great divide: MCP Client vs MCP Server\" title=\"Direct link to The great divide: MCP Client vs MCP Server\">​</a></h2>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"mcp-client-building-the-foundation\">MCP Client: Building the Foundation<a href=\"https://didierlopes.com/blog/are-you-team-mcp-client-or-server#mcp-client-building-the-foundation\" class=\"hash-link\" aria-label=\"Direct link to MCP Client: Building the Foundation\" title=\"Direct link to MCP Client: Building the Foundation\">​</a></h3>\n<p>They focus on creating the interfaces, user experiences, and underlying systems that enable AI interactions. Think of them as the architects of the AI-powered financial ecosystem.</p>\n<p><strong>MCP Clients are the infrastructure players.</strong></p>\n<ul>\n<li>Own the user interface and experience</li>\n<li>Control the infrastructure and orchestration layer</li>\n<li>Integrate multiple data sources and tools</li>\n<li>Focus on platform scalability and reliability</li>\n<li>Invest heavily in UI/UX and system architecture</li>\n</ul>\n<br>\n<p><strong>The Client advantage</strong>: When you control the client layer, you own the relationship with the end user. You decide which tools get surfaced, how data is presented, and ultimately how decisions get made. In financial services, this translates to enormous influence over trading decisions, investment strategies, and risk management processes.</p>\n<p>OpenBB falls squarely in this category, alongside Claude, ChatGPT, and other financial AI chat interfaces. But so do platforms like Replit and Cursor – essentially any product that empowers creation and interaction. At OpenBB, we see ourselves as that critical bridge between data and AI through intuitive UI and workflows, where MCP Servers become another seamless way for data to flow through our interface.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"mcp-server-powering-the-engine\">MCP Server: Powering the Engine<a href=\"https://didierlopes.com/blog/are-you-team-mcp-client-or-server#mcp-server-powering-the-engine\" class=\"hash-link\" aria-label=\"Direct link to MCP Server: Powering the Engine\" title=\"Direct link to MCP Server: Powering the Engine\">​</a></h3>\n<p>They focus on providing specialized capabilities, datasets, and domain expertise that clients can leverage through standardized protocols.</p>\n<p><strong>MCP Servers are the data and tools specialists.</strong></p>\n<ul>\n<li>Deep specialization in specific data domains</li>\n<li>Focus on tool development and API optimization</li>\n<li>Emphasis on data quality, accuracy, and coverage</li>\n<li>Building for integration rather than end-user interaction</li>\n<li>Competing on the quality and uniqueness of their offerings</li>\n</ul>\n<p><strong>The Server advantage</strong>: Specialized servers can become indispensable by providing unique, high-quality data or capabilities that multiple clients depend on. Think market data feeds, compliance tools, or proprietary analytics engines.</p>\n<p>S&amp;P Global, FactSet, and Snowflake dominate this domain - they're the engine room powering the financial ecosystem.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"the-strategic-implications\">The Strategic Implications<a href=\"https://didierlopes.com/blog/are-you-team-mcp-client-or-server#the-strategic-implications\" class=\"hash-link\" aria-label=\"Direct link to The Strategic Implications\" title=\"Direct link to The Strategic Implications\">​</a></h2>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"for-mcp-clients-the-high-stakes-high-reward-path\">For MCP Clients: The high-stakes, high-reward path<a href=\"https://didierlopes.com/blog/are-you-team-mcp-client-or-server#for-mcp-clients-the-high-stakes-high-reward-path\" class=\"hash-link\" aria-label=\"Direct link to For MCP Clients: The high-stakes, high-reward path\" title=\"Direct link to For MCP Clients: The high-stakes, high-reward path\">​</a></h3>\n<p>Choosing the client path means betting on your ability to create the best user experience and orchestrate the most valuable ecosystem. The market opportunity is massive - you're essentially competing to become the \"operating system\" for AI-powered finance.</p>\n<p><strong>The upside is enormous</strong>: Control the client, and you control how the entire ecosystem gets monetized. You capture value from every interaction, every decision, and every workflow.</p>\n<p><strong>But the challenges are significant:</strong></p>\n<ul>\n<li>Requires massive upfront investment in infrastructure</li>\n<li>Complex technical challenges around integration and orchestration</li>\n<li>Must maintain relationships with numerous server providers</li>\n<li>User acquisition and retention in a crowded market</li>\n<li>Continuous innovation pressure to stay ahead of competitors</li>\n</ul>\n<p><strong>Success depends on differentiation</strong>: In a client-first world, your positioning becomes critical. Are you the platform for institutional traders? Wealth managers? Risk analysts? Do you provide better insights on server data than competitors? Are you more secure? Do you enable on-premise deployment? Can you integrate with firms' existing workflows? Your answers determine your survival.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"for-mcp-servers-the-specialization-game\">For MCP Servers: The specialization game<a href=\"https://didierlopes.com/blog/are-you-team-mcp-client-or-server#for-mcp-servers-the-specialization-game\" class=\"hash-link\" aria-label=\"Direct link to For MCP Servers: The specialization game\" title=\"Direct link to For MCP Servers: The specialization game\">​</a></h3>\n<p>Choosing the server path means focusing on what you do best and offering superior data and tools for integration into multiple client ecosystems. You become a crucial piece of a larger puzzle rather than trying to solve the entire equation yourself. Your success depends on attaching to the best MCP clients – they're your distribution window.</p>\n<p><strong>The benefits include</strong>:</p>\n<ul>\n<li>Lower barrier to entry and faster time to market</li>\n<li>Ability to focus resources on core competencies</li>\n<li>Multiple revenue streams through various client integrations</li>\n<li>Less direct competition with big tech platforms</li>\n</ul>\n<br>\n<p><strong>But the competitive landscape is brutal</strong>:</p>\n<ul>\n<li>Intense competition with numerous specialized providers</li>\n<li>Commoditization risk as protocols standardize</li>\n<li>Dependence on client platforms for distribution</li>\n<li>Constant pressure to prove unique value</li>\n</ul>\n<br>\n<p><strong>The monopoly advantage</strong>: Large, established players have significant advantages in the server game. Their brand recognition, existing distribution channels, and resource advantages make it difficult for smaller players to compete on equal footing.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"why-you-cant-play-both-sides\">Why you can’t play both sides<a href=\"https://didierlopes.com/blog/are-you-team-mcp-client-or-server#why-you-cant-play-both-sides\" class=\"hash-link\" aria-label=\"Direct link to Why you can’t play both sides\" title=\"Direct link to Why you can’t play both sides\">​</a></h2>\n<p>Many financial companies are tempted to hedge their bets by building both client and server capabilities. For years, they have:</p>\n<ul>\n<li>S&amp;P has a data business and CapIQ</li>\n<li>FactSet has a data business and FactSet Workstation</li>\n<li>LSEG has a data business and LSEG Workspace</li>\n</ul>\n<p>You get the gist.</p>\n<p>My opinion? <strong>These firms will evolve to be data businesses only</strong> – but I'll write about that in another post. While they'll likely try approaching this problem from both sides (there's money to be made on both), this approach is <strong>fundamentally flawed</strong>. Here's why:</p>\n<p><strong>1. Conflicting incentives</strong></p>\n<p>As a client, you want to integrate the best servers available – even if they compete with your own server offerings. As a server, you want maximum distribution – even through clients that compete with your own platform. These incentives directly conflict.</p>\n<p><strong>2. Resource dilution</strong></p>\n<p>Building world-class client experiences requires completely different investments than creating best-in-class server capabilities. Trying to do both means neither gets the focus and resources needed to truly excel.</p>\n<p><strong>3. Market perception</strong></p>\n<p>Clients may hesitate to depend on servers from companies that also compete with them at the platform level. Similarly, end users might question whether a client platform is truly optimized when the company has competing interests in promoting their own server capabilities.</p>\n<p><strong>4. Innovation Bottlenecks</strong></p>\n<p>The rapid pace of AI advancement demands focus. Companies trying to innovate on both fronts often find themselves behind specialized competitors who can move faster and iterate more quickly.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"the-moment-of-truth\">The moment of truth<a href=\"https://didierlopes.com/blog/are-you-team-mcp-client-or-server#the-moment-of-truth\" class=\"hash-link\" aria-label=\"Direct link to The moment of truth\" title=\"Direct link to The moment of truth\">​</a></h2>\n<p>The MCP ecosystem is still emerging, giving companies a narrow window to make this strategic decision and commit fully to their chosen path. Those who try to straddle both worlds will find themselves outmaneuvered by focused competitors who have made clear strategic choices.</p>\n<p><strong>For established financial institutions</strong>: Your legacy systems and existing client relationships might naturally point you toward one path or the other. Don't fight this, lean into your strengths.</p>\n<p><strong>For fintech startups</strong>: Your decision here will define your entire business model, funding requirements, and competitive strategy. Choose wisely.</p>\n<p>The question isn't whether MCP will transform financial services - it will.</p>\n<p>The question is whether you'll be controlling the transformation as a Client or powering it as a Server.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/are-you-team-mcp-client-or-server",
            "title": "Are you team MCP Client or Server?",
            "summary": "The Model Context Protocol (MCP) forces a strategic choice on financial services companies - become a Client, building AI user experiences, or a Server, providing specialized data and tools. This post explores the implications of this divide.",
            "date_modified": "2025-07-29T00:00:00.000Z",
            "tags": [
                "mcp",
                "ai",
                "financial-services",
                "strategy",
                "fintech",
                "openbb"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/can-we-kill-the-term-vibe-coding",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-07-23-can-we-kill-the-term-vibe-coding.webp\"></p>\n<p>The term 'vibe coding' undermines the strategic work of delegating tasks to AI. This post argues for a shift in perspective towards 'outcome-driven development' as a more accurate description of the future of software engineering.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>Let's be honest: \"vibe coding\" is a terrible term that needs to die. It makes something fundamentally serious sound frivolous and hand-wavy, when what we're actually talking about is sophisticated work delegation and abstraction.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"whats-really-happening\">What's really happening<a href=\"https://didierlopes.com/blog/can-we-kill-the-term-vibe-coding#whats-really-happening\" class=\"hash-link\" aria-label=\"Direct link to What's really happening\" title=\"Direct link to What's really happening\">​</a></h2>\n<p>When someone says they are \"vibe coding\" they aren't just throwing code at a wall and hoping something sticks. They're operating at a higher level of abstraction, defining outcomes and delegating implementation details to AI systems.</p>\n<p>This is strategic work allocation, not mystical programming.</p>\n<p>Think about it this way: if I ask you to \"get something done\" and you deliver exactly what I need, I'm not doing \"vibe working\". I'm managing, delegating, and operating at the appropriate level of abstraction for my role.</p>\n<p>The same principle applies here.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"coding-has-always-been-about-outcomes\">Coding has always been about outcomes<a href=\"https://didierlopes.com/blog/can-we-kill-the-term-vibe-coding#coding-has-always-been-about-outcomes\" class=\"hash-link\" aria-label=\"Direct link to Coding has always been about outcomes\" title=\"Direct link to Coding has always been about outcomes\">​</a></h2>\n<p>Here's the thing nobody talks about: <strong>no one codes for the sake of coding</strong>.</p>\n<p>Coding is a means to an end.</p>\n<p>There's always a goal, always a problem to solve, always a deliverable to create. Whether you're writing assembly by hand or describing requirements to an AI, you're still pursuing the same fundamental objective.</p>\n<p>The difference isn't in the seriousness or legitimacy of the work, it's in the level of abstraction you're operating at.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"what-were-actually-doing\">What we're actually doing<a href=\"https://didierlopes.com/blog/can-we-kill-the-term-vibe-coding#what-were-actually-doing\" class=\"hash-link\" aria-label=\"Direct link to What we're actually doing\" title=\"Direct link to What we're actually doing\">​</a></h2>\n<p>When we delegate coding tasks to AI, we're:</p>\n<ul>\n<li><strong>Defining clear requirements and constraints</strong></li>\n<li><strong>Specifying expected outcomes and success criteria</strong></li>\n<li><strong>Monitoring and validating the implementation</strong></li>\n<li><strong>Iterating and refining based on results</strong></li>\n</ul>\n<p>This isn't \"vibing\".</p>\n<p>This is structured problem-solving at a higher level of abstraction.</p>\n<p>It's the natural evolution of how we interact with increasingly sophisticated tools.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"why-the-term-matters\">Why the Term Matters<a href=\"https://didierlopes.com/blog/can-we-kill-the-term-vibe-coding#why-the-term-matters\" class=\"hash-link\" aria-label=\"Direct link to Why the Term Matters\" title=\"Direct link to Why the Term Matters\">​</a></h2>\n<p>Language shapes perception. When we call this \"vibe coding\" we're undermining the legitimacy of a genuine shift in how software development works.</p>\n<p>We're making it sound like guesswork instead of strategic delegation.</p>\n<p>This matters because:</p>\n<ul>\n<li><strong>It minimizes the skill required</strong> to effectively delegate to AI systems</li>\n<li><strong>It suggests randomness</strong> when the process is actually quite deliberate</li>\n<li><strong>It creates resistance</strong> from developers who see it as \"not real coding\"</li>\n<li><strong>It obscures the real value</strong> of working at higher levels of abstraction</li>\n</ul>\n<br>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"a-better-framework\">A better framework<a href=\"https://didierlopes.com/blog/can-we-kill-the-term-vibe-coding#a-better-framework\" class=\"hash-link\" aria-label=\"Direct link to A better framework\" title=\"Direct link to A better framework\">​</a></h2>\n<p>Instead of \"vibe coding\", let's talk about what this really is:</p>\n<ul>\n<li>\n<p><strong>Outcome-driven development</strong>: You define what you want to achieve, specify the constraints and requirements, and delegate the implementation details to the most appropriate resource—whether that's a human developer, an AI system, or a combination of both.</p>\n</li>\n<li>\n<p><strong>Abstraction-level management</strong>: You're choosing to operate at the level where you can be most effective, rather than getting bogged down in implementation details that can be handled elsewhere.</p>\n</li>\n<li>\n<p><strong>Strategic delegation</strong>: You're allocating work to the resources best suited to handle it efficiently and effectively.</p>\n</li>\n</ul>\n<br>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"the-real-question\">The real question<a href=\"https://didierlopes.com/blog/can-we-kill-the-term-vibe-coding#the-real-question\" class=\"hash-link\" aria-label=\"Direct link to The real question\" title=\"Direct link to The real question\">​</a></h2>\n<p>The question isn't whether this approach is legitimate, <strong>it obviously is</strong>.</p>\n<p>The question is whether we're going to embrace more accurate language that reflects the sophistication of what we're actually doing, or continue to use terms that make it sound like we're just \"vibing\" our way through software development.</p>\n<p>Coding has always been about solving problems and creating value. The tools and methods evolve, but the fundamental purpose remains the same. It's time our language evolved too.</p>\n<p>We should kill the term \"vibe coding\" and start talking about what this really is: <strong>the future of software development</strong>.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/can-we-kill-the-term-vibe-coding",
            "title": "Can we kill the term \"vibe coding\"?",
            "summary": "The term 'vibe coding' undermines the strategic work of delegating tasks to AI. This post argues for a shift in perspective towards 'outcome-driven development' as a more accurate description of the future of software engineering.",
            "date_modified": "2025-07-23T00:00:00.000Z",
            "tags": [
                "ai",
                "software-development",
                "future-of-code",
                "developer-productivity",
                "llms",
                "engineering-philosophy",
                "vibe-coding"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/is-prompt-engineering-dead-the-case-for-test-driven-ai-development",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-07-17-is-prompt-engineering-dead-the-case-for-test-driven-ai-development.webp\"></p>\n<p>This post explores Test-Driven AI Development, where AI writes its own tests and prompts, potentially making manual prompt engineering obsolete. It covers how self-improving AI systems can be built and the implications of this paradigm shift.</p>\n<!-- -->\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>I learned about Test Driven Development (TDD) a few years ago while working as a Firmware Engineer. What I didn't expect was how this traditional methodology would evolve into something that could fundamentally change how we build AI systems, and potentially make prompt engineering obsolete.</p>\n<p><strong>The thesis:</strong> If AI can write comprehensive tests from a PRD AND automatically generate prompts to pass those tests, then manual prompt engineering becomes as outdated as manually optimizing low-level assembly code.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"test-driven-development-a-quick-refresher\">Test Driven Development: A quick refresher<a href=\"https://didierlopes.com/blog/is-prompt-engineering-dead-the-case-for-test-driven-ai-development#test-driven-development-a-quick-refresher\" class=\"hash-link\" aria-label=\"Direct link to Test Driven Development: A quick refresher\" title=\"Direct link to Test Driven Development: A quick refresher\">​</a></h2>\n<p>Skip this if you're familiar with TDD.</p>\n<p>Test-driven development is a software development process where tests are written before the actual code. The core process, known as \"Red-Green-Refactor\" involves writing a failing test, writing the minimal code to pass it, and then refactoring the code.</p>\n<div class=\"language-python codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-python codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token comment\" style=\"color:rgb(98, 114, 164)\"># Test first</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">def</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(80, 250, 123)\">test_discount</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    </span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">assert</span><span class=\"token plain\"> calculate_discount</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token number\">100</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> </span><span class=\"token number\">0.1</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token plain\"> </span><span class=\"token operator\">==</span><span class=\"token plain\"> </span><span class=\"token number\">90</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\"></span><span class=\"token comment\" style=\"color:rgb(98, 114, 164)\"># Then minimal code</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">def</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(80, 250, 123)\">calculate_discount</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token plain\">price</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> rate</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    </span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">return</span><span class=\"token plain\"> price </span><span class=\"token operator\">*</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token number\">1</span><span class=\"token plain\"> </span><span class=\"token operator\">-</span><span class=\"token plain\"> rate</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><br></span></code></pre></div></div>\n<p>The traditional flow looks like this:</p>\n<div class=\"language-text codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-text codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Mock data  ────&gt;  Code  ────&gt;  Output × Tests</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">                   ↑              │</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">          Refactor │              │</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">                   └── Error ←────┘</span><br></span></code></pre></div></div>\n<p>The cycle continues: run the test, refactor the code, run the test again, until all tests pass.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"tdd-with-ai-first-evolution\">TDD with AI: First evolution<a href=\"https://didierlopes.com/blog/is-prompt-engineering-dead-the-case-for-test-driven-ai-development#tdd-with-ai-first-evolution\" class=\"hash-link\" aria-label=\"Direct link to TDD with AI: First evolution\" title=\"Direct link to TDD with AI: First evolution\">​</a></h2>\n<p>TDD with AI becomes much easier. The concept is the same, except the user isn't required to refactor the code manually or run the tests.</p>\n<div class=\"language-text codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-text codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Mock data  ────&gt;  Code  ────&gt;  Output × Tests</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">                   ↑              │</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">              AI   │              │</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">                   └── Error ←────┘</span><br></span></code></pre></div></div>\n<p>The process simplifies to: ask AI to run the tests and fix any errors until they pass.</p>\n<p><strong>Critical lesson learned:</strong> You must explicitly tell the AI it cannot modify the tests. Otherwise, it takes the easy path and just changes failing tests to pass. (This literally happened to me! 🙃)</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"prompt-test-driven-development-the-paradigm-shift\">Prompt-Test Driven Development: The paradigm shift<a href=\"https://didierlopes.com/blog/is-prompt-engineering-dead-the-case-for-test-driven-ai-development#prompt-test-driven-development-the-paradigm-shift\" class=\"hash-link\" aria-label=\"Direct link to Prompt-Test Driven Development: The paradigm shift\" title=\"Direct link to Prompt-Test Driven Development: The paradigm shift\">​</a></h2>\n<p>Sometimes you want to test the agentic capabilities of your model. Assuming the tools are implemented correctly, you're actually testing the instructions - i.e. the prompt.</p>\n<p>Prompt engineering is this whole new field that has emerged with LLMs. It is defined as: <em>\"the practice of crafting specific and effective instructions, known as prompts, to guide generative AI models in producing desired outputs\"</em>. Chip Huyen's <a href=\"https://www.oreilly.com/library/view/ai-engineering/9781098166298/\" target=\"_blank\" rel=\"noopener noreferrer\">AI Engineering book</a> has an entire section on the topic (I highly recommend).</p>\n<p>When testing prompts, the flow becomes:</p>\n<div class=\"language-text codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-text codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Mock data  ────&gt;  Prompt → LLM  ────&gt;  Output × Tests</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">                     ↑                    │</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">           Improve   │                    │</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">           Prompt    │                    │</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">                     └──── Error ←────────┘</span><br></span></code></pre></div></div>\n<p>Your \"tests\" become example scenarios with expected AI behaviors:</p>\n<div class=\"language-text codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-text codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Test: Customer asks \"I want a refund\"</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Expected: AI checks return policy first</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Current behavior: AI immediately offers refund</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Result: ❌ FAIL</span><br></span></code></pre></div></div>\n<p>Your \"code\" is now the prompt that instructs the AI how to behave. When tests fail, you improve the prompt instead of traditional code.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"the-breakthrough-self-improving-ai\">The breakthrough: Self-improving AI<a href=\"https://didierlopes.com/blog/is-prompt-engineering-dead-the-case-for-test-driven-ai-development#the-breakthrough-self-improving-ai\" class=\"hash-link\" aria-label=\"Direct link to The breakthrough: Self-improving AI\" title=\"Direct link to The breakthrough: Self-improving AI\">​</a></h2>\n<p>The same way we removed manual refactoring from traditional TDD, we can remove the human from prompt improvement:</p>\n<div class=\"language-text codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-text codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Mock data  ──&gt;  Prompt + LLM + Tools  ───&gt;  Output × Tests</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">                       ↑                           │</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">                    AI │                           │</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">                       └──── Error ←───────────────┘</span><br></span></code></pre></div></div>\n<p>Here's where it gets interesting: <strong>the AI agent itself is a combination of Prompt + LLM + Tools</strong>.</p>\n<p>When we use the same LLM to improve the prompt as the one our agent is built on, we create a self-reinforcing loop.</p>\n<p align=\"center\"><img width=\"900\" src=\"https://didierlopes.com/blog/2025-07-17-is-prompt-engineering-dead-the-case-for-test-driven-ai-development_1.webp\"><em style=\"opacity:0.9\">Real example of me utilizing this for our production tests</em></p>\n<p><strong>Example in action:</strong></p>\n<div class=\"language-text codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-text codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Test: Customer asks \"I want a refund\"</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Current Prompt: \"You are a helpful customer service agent\".</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Expected: AI checks return policy first</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Current behavior: AI immediately offers refund</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">AI Self-Analysis:</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">\"I failed because I offered a refund without checking policy. </span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">The prompt lacks specific instructions about policy verification.\"</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">AI-Generated Improvement: </span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">\"You are a customer service agent. Always check the return </span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">policy before processing refund requests. If eligible, explain </span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">the process. If not, explain why and offer alternatives.\"</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Test Result: ✅ PASS</span><br></span></code></pre></div></div>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"the-elegant-insight-no-external-execution-required\">The elegant insight: No external execution required<a href=\"https://didierlopes.com/blog/is-prompt-engineering-dead-the-case-for-test-driven-ai-development#the-elegant-insight-no-external-execution-required\" class=\"hash-link\" aria-label=\"Direct link to The elegant insight: No external execution required\" title=\"Direct link to The elegant insight: No external execution required\">​</a></h2>\n<p>The AI isn't even required to run tests using your framework. It can evaluate outcomes by examining the data directly.</p>\n<p>Since the AI helping you improve the prompt is the same as the one in production, it can \"recreate\" the output you would see just by looking at the code and data. No logs required, the model can predict its own behavior.</p>\n<p>When you show an AI:</p>\n<ul>\n<li>Current prompt</li>\n<li>Mock input data</li>\n<li>Expected output</li>\n</ul>\n<p>The AI can immediately identify mismatches and generate improvements.</p>\n<p><strong>The feedback loop happens entirely within the AI's reasoning process</strong>, making iteration nearly instantaneous.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"the-death-of-prompt-engineering-test-coverage-as-the-new-paradigm\">The death of Prompt Engineering: Test Coverage as the new paradigm<a href=\"https://didierlopes.com/blog/is-prompt-engineering-dead-the-case-for-test-driven-ai-development#the-death-of-prompt-engineering-test-coverage-as-the-new-paradigm\" class=\"hash-link\" aria-label=\"Direct link to The death of Prompt Engineering: Test Coverage as the new paradigm\" title=\"Direct link to The death of Prompt Engineering: Test Coverage as the new paradigm\">​</a></h2>\n<p>Here's the revolutionary implication: <strong>if AI can generate both comprehensive test coverage from a PRD AND the prompts to pass those tests, then manual prompt engineering becomes obsolete</strong>.</p>\n<p>Consider this progression:</p>\n<p><strong>Manual Prompt Engineering (Current State):</strong></p>\n<div class=\"language-text codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-text codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Human writes requirements → Human crafts prompts → Test in production → Manual debugging</span><br></span></code></pre></div></div>\n<p><strong>Test-Driven AI Development (Future State):</strong></p>\n<div class=\"language-text codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-text codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Human writes requirements → AI generates comprehensive tests → AI generates optimal prompts → Continuous self-improvement</span><br></span></code></pre></div></div>\n<p>With sufficient test coverage, prompts become an automatically generated implementation detail—like compiled machine code that you never need to see or manually optimize.</p>\n<p><strong>The new workflow</strong>:</p>\n<ol>\n<li>Define behavioral requirements through examples</li>\n<li>AI generates exhaustive test scenarios covering edge cases</li>\n<li>AI automatically generates and refines prompts to pass all tests</li>\n<li>System continuously improves itself as new test cases are added</li>\n</ol>\n<br>\n<p><strong>Instead of asking \"How do I prompt this AI?\"</strong> we ask <strong>\"How do I comprehensively test this behavior?\"</strong></p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"moving-toward-singularity\">Moving toward singularity<a href=\"https://didierlopes.com/blog/is-prompt-engineering-dead-the-case-for-test-driven-ai-development#moving-toward-singularity\" class=\"hash-link\" aria-label=\"Direct link to Moving toward singularity\" title=\"Direct link to Moving toward singularity\">​</a></h2>\n<p>This is where we're approaching something unprecedented: AI that can fix itself, with humans only adding tests to guide its behavior.</p>\n<p>The key insight: instead of retraining models with new data (expensive, slow), we can improve behavior through prompt refinement (fast, cheap, immediate).</p>\n<p>The system can literally predict and fix its own behavior through disciplined self-reflection.</p>\n<p><strong>Prompt engineering doesn't disappear—it becomes automated.</strong></p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"the-control-systems-perspective\">The control systems perspective<a href=\"https://didierlopes.com/blog/is-prompt-engineering-dead-the-case-for-test-driven-ai-development#the-control-systems-perspective\" class=\"hash-link\" aria-label=\"Direct link to The control systems perspective\" title=\"Direct link to The control systems perspective\">​</a></h2>\n<p>This reminds me of my MSc in Control Systems, where we learned that systems have poles that can be on the negative side (stable) or positive side (unstable).</p>\n<p>The same principle applies here:</p>\n<ul>\n<li><strong>Stable:</strong> AI generates genuinely better prompts → improved performance → convergence</li>\n<li><strong>Unstable:</strong> AI games the system → overfitting to tests → real-world failure</li>\n</ul>\n<br>\n<p><strong>Warning signs of instability:</strong></p>\n<ul>\n<li>Prompts becoming absurdly specific to test cases</li>\n<li>AI suggesting test modifications \"for clarity\"</li>\n<li>Tests passing but real-world performance degrading</li>\n</ul>\n<br>\n<p><strong>Maintaining stability:</strong></p>\n<ul>\n<li>Lock test cases as immutable</li>\n<li>Monitor real-world performance alongside test performance</li>\n<li>Explicitly forbid test modifications in improvement instructions</li>\n</ul>\n<br>\n<p>The incentive should always be to pass the tests AS THEY ARE.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"the-revolutionary-potential\">The revolutionary potential<a href=\"https://didierlopes.com/blog/is-prompt-engineering-dead-the-case-for-test-driven-ai-development#the-revolutionary-potential\" class=\"hash-link\" aria-label=\"Direct link to The revolutionary potential\" title=\"Direct link to The revolutionary potential\">​</a></h2>\n<p>This isn't just about better prompts—it's about creating AI systems that can debug their own reasoning processes in real-time.</p>\n<p>We're moving toward AI that doesn't just follow instructions, but improves the instructions themselves through disciplined self-reflection.</p>\n<p>Prompt engineering as we know it may be dead, which is scary because this is how we \"control\" AI.</p>\n<p>The question is: <strong>are we ready to let AI systems write their own prompt</strong>, or do we still need the illusion of control that manual prompting provides?</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/is-prompt-engineering-dead-the-case-for-test-driven-ai-development",
            "title": "Is Prompt Engineering dead? The case for Test-Driven AI Development",
            "summary": "This post explores Test-Driven AI Development, where AI writes its own tests and prompts, potentially making manual prompt engineering obsolete. It covers how self-improving AI systems can be built and the implications of this paradigm shift.",
            "date_modified": "2025-07-17T00:00:00.000Z",
            "tags": [
                "ai",
                "prompt-engineering",
                "llm",
                "software-development",
                "automation",
                "agentic-ai",
                "self-improving-ai",
                "test-driven-development",
                "control-systems"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/finances-oceangate-moment-the-ai-adoption-disaster-waiting-to-happen",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-07-09-finances-oceangate-moment-the-ai-adoption-disaster-waiting-to-happen.webp\"></p>\n<p>The financial industry's rush to adopt AI without proper data security is creating an 'OceanGate moment' - a disaster waiting to happen. This post explores the risks of reckless AI implementation and charts a safer path forward through on-premise and local model deployment.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>The more I learn about how financial firms are adopting AI, the more convinced I become that we're heading toward an inevitable reckoning.</p>\n<p>There's a chilling scene in the OceanGate documentary trailer where Rob McCallum, a former advisor to OceanGate, observes:</p>\n<blockquote>\n<p>\"There was no way of knowing when Titan would fail. But it was a mathematical certainty that it would fail.\"</p>\n</blockquote>\n<br>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-07-09-finances-oceangate-moment-the-ai-adoption-disaster-waiting-to-happen_1.webp\"></p>\n<p>This wasn't about predicting the exact moment of catastrophe. It was about recognizing that the submarine's fundamental design flaws made disaster inevitable.</p>\n<p>This is precisely where we stand today with AI adoption in finance.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"three-colliding-forces\">Three colliding forces<a href=\"https://didierlopes.com/blog/finances-oceangate-moment-the-ai-adoption-disaster-waiting-to-happen#three-colliding-forces\" class=\"hash-link\" aria-label=\"Direct link to Three colliding forces\" title=\"Direct link to Three colliding forces\">​</a></h2>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"leadership-fomo-vs-industry-inertia\">Leadership FOMO vs. Industry inertia<a href=\"https://didierlopes.com/blog/finances-oceangate-moment-the-ai-adoption-disaster-waiting-to-happen#leadership-fomo-vs-industry-inertia\" class=\"hash-link\" aria-label=\"Direct link to Leadership FOMO vs. Industry inertia\" title=\"Direct link to Leadership FOMO vs. Industry inertia\">​</a></h3>\n<p>The financial industry moves at glacial speed. Many investment firms today still operate without AI capabilities, lack dedicated AI engineers, or worse - have no coherent data strategy whatsoever.</p>\n<p>Yet these same leaders consume report after report showcasing dramatic efficiency gains at AI-forward companies.</p>\n<p>The result? FOMO is forcing an inherently cautious industry to abandon its natural risk-averse instincts.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"the-technology-diffusion-flip\">The technology diffusion flip<a href=\"https://didierlopes.com/blog/finances-oceangate-moment-the-ai-adoption-disaster-waiting-to-happen#the-technology-diffusion-flip\" class=\"hash-link\" aria-label=\"Direct link to The technology diffusion flip\" title=\"Direct link to The technology diffusion flip\">​</a></h3>\n<p>Andrej Karpathy made a crucial observation that explains why this situation is unprecedented:</p>\n<blockquote>\n<p>\"LLMs flip the direction of technology diffusion that is usually present in technology. [...] Typically it is the government and corporations that are the first users, because it's new and expensive, etc. And it only later diffuses to consumers.\"</p>\n</blockquote>\n<br>\n<p>Read his full analysis <a href=\"https://x.com/karpathy/status/1909308143156240538\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<p align=\"center\"><img width=\"400\" src=\"https://didierlopes.com/blog/2025-07-09-finances-oceangate-moment-the-ai-adoption-disaster-waiting-to-happen_2.webp\"></p>\n<p>For the first time in corporate history, employees have access to transformative technology before their institutions can properly evaluate and control it.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"the-individual-productivity-arms-race\">The individual productivity arms race<a href=\"https://didierlopes.com/blog/finances-oceangate-moment-the-ai-adoption-disaster-waiting-to-happen#the-individual-productivity-arms-race\" class=\"hash-link\" aria-label=\"Direct link to The individual productivity arms race\" title=\"Direct link to The individual productivity arms race\">​</a></h3>\n<p>Employees and interns at these firms face an impossible situation. They watch peers in tech, consulting, and other industries leverage AI for 10x productivity gains while they're constrained by institutional caution.</p>\n<p>The social pressure is immense.</p>\n<p>The career advantages are obvious.</p>\n<p>When someone discovers they can draft reports in minutes instead of hours using ChatGPT, the secret spreads like wildfire. Soon, not using AI becomes a career-limiting move.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"the-inevitable-escalation\">The inevitable escalation<a href=\"https://didierlopes.com/blog/finances-oceangate-moment-the-ai-adoption-disaster-waiting-to-happen#the-inevitable-escalation\" class=\"hash-link\" aria-label=\"Direct link to The inevitable escalation\" title=\"Direct link to The inevitable escalation\">​</a></h2>\n<p>What starts as something innocent, such as using AI for basic chat queries, quickly escalates:</p>\n<ul>\n<li><strong>Week 1</strong>: \"I'll just use it for brainstorming\"</li>\n<li><strong>Week 2</strong>: \"Let me upload this one document to help with my analysis\"</li>\n<li><strong>Week 3</strong>: \"If I can provide these few reports, then it will save me so much time!\"</li>\n<li><strong>Week 4</strong>: \"F*** it, everyone's doing it. What's the worse that can happen?\"</li>\n</ul>\n<br>\n<p>In a few months, you can have entire teams processing confidential client data through external AI services</p>\n<p>Each step feels reasonable in isolation.</p>\n<p>Collectively, they represent a massive compliance and security breach waiting to happen.</p>\n<p>Consider the recent case where <a href=\"https://www.forbes.com/sites/siladityaray/2023/05/02/samsung-bans-chatgpt-and-other-chatbots-for-employees-after-sensitive-code-leak/\" target=\"_blank\" rel=\"noopener noreferrer\">Samsung employees inadvertently leaked sensitive code by using ChatGPT for debugging</a>.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"the-cost-of-inaction-vs-reckless-action\">The cost of inaction vs. reckless action<a href=\"https://didierlopes.com/blog/finances-oceangate-moment-the-ai-adoption-disaster-waiting-to-happen#the-cost-of-inaction-vs-reckless-action\" class=\"hash-link\" aria-label=\"Direct link to The cost of inaction vs. reckless action\" title=\"Direct link to The cost of inaction vs. reckless action\">​</a></h3>\n<p><strong>Traditional Approach Costs:</strong></p>\n<ul>\n<li>substantial productivity disadvantage vs. AI-enabled competitors</li>\n<li>Talent retention challenges as top performers seek AI-forward environments</li>\n<li>Gradual market share erosion to more agile competitors</li>\n</ul>\n<br>\n<p><strong>Reckless AI Adoption Costs:</strong></p>\n<ul>\n<li>Regulatory violations</li>\n<li>Data breaches</li>\n<li>Client trust erosion and potential lawsuits</li>\n<li>Competitive intelligence leakage</li>\n</ul>\n<br>\n<p>Something has to give - and history suggests it won't be pretty when it does.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"the-path-forward\">The path forward<a href=\"https://didierlopes.com/blog/finances-oceangate-moment-the-ai-adoption-disaster-waiting-to-happen#the-path-forward\" class=\"hash-link\" aria-label=\"Direct link to The path forward\" title=\"Direct link to The path forward\">​</a></h2>\n<p>Fortunately, forward-thinking firms are already charting safer courses:</p>\n<ul>\n<li><strong>Policies to not push any data outside their premises</strong>: Implement strict data governance preventing any information from leaving company premises. This approach sacrifices efficiency gains for security but may prove insufficient as competitive pressures mount. (ok)</li>\n<li><strong>Utilizing AI software on-premise</strong>: Deploy enterprise AI software within company infrastructure, maintaining data control while enabling productivity gains. Solutions like Microsoft's enterprise ChatGPT or Google's Vertex AI offer this middle ground, and firms are in control with their relationship with the AI labs. (good)</li>\n<li><strong>Running their own AI models locally</strong>: Run proprietary AI models on company hardware, achieving complete data sovereignty while maintaining cutting-edge capabilities. (best)</li>\n</ul>\n<br>\n<p>The viability of running models locally has dramatically improved. While the performance gap between closed and open models remains significant, it's narrowing rapidly.</p>\n<p>Newest LLMs are no longer showing exponential improvements but incremental only. This means that the open weight models are catching up, and - likely - in a long enough time horizon the performance of closed and open models converges.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"in-practice\">In practice<a href=\"https://didierlopes.com/blog/finances-oceangate-moment-the-ai-adoption-disaster-waiting-to-happen#in-practice\" class=\"hash-link\" aria-label=\"Direct link to In practice\" title=\"Direct link to In practice\">​</a></h2>\n<p>We've implemented this philosophy in the <a href=\"https://openbb.co/products/workspace\" target=\"_blank\" rel=\"noopener noreferrer\">OpenBB Workspace</a>.</p>\n<p align=\"center\"><img width=\"900\" src=\"https://didierlopes.com/blog/2025-07-09-finances-oceangate-moment-the-ai-adoption-disaster-waiting-to-happen_3.webp\"></p>\n<p>Our product enables complete on-premises deployment <strong>with local model integration</strong>, giving financial professionals AI-powered analysis without data sovereignty concerns.</p>\n<p>The question isn't whether AI will transform finance - it's whether your firm will control that transformation or become its victim.</p>\n<p>If you're ready to discuss how to implement AI safely and strategically within your organization, let's talk. Our product helps financial firms navigate this transition without compromising security, compliance, or competitive position.</p>\n<p>The mathematical certainty of failure only applies to those who don't listen to the cracks in the ship.</p>\n<div style=\"border-bottom:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>I believe in this so much that I actually added a <a href=\"https://didierlopes.com/chat\" target=\"_blank\" rel=\"noopener noreferrer\">Chat page</a> to my personal website that allows users to run open-weight models on their machine, via Ollama, with access to data from my blogposts.</p>\n<p align=\"center\"><img width=\"900\" src=\"https://didierlopes.com/blog/2025-07-09-finances-oceangate-moment-the-ai-adoption-disaster-waiting-to-happen_4.webp\"></p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/finances-oceangate-moment-the-ai-adoption-disaster-waiting-to-happen",
            "title": "Finance's OceanGate moment - The AI adoption disaster waiting to happen",
            "summary": "The financial industry's rush to adopt AI without proper data security is creating an 'OceanGate moment' - a disaster waiting to happen. This post explores the risks of reckless AI implementation and charts a safer path forward through on-premise and local model deployment.",
            "date_modified": "2025-07-09T00:00:00.000Z",
            "tags": [
                "ai",
                "finance",
                "risk-management",
                "data-security",
                "llm",
                "leadership",
                "strategy",
                "data-leakage"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/bring-back-your-corner-of-the-internet",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-07-02-bring-back-your-corner-of-the-internet.webp\"></p>\n<p>The web has become bland and uniform. It's time to bring back the weird, wonderful, and deeply personal websites that once made the internet magical. With AI, the limit aren't skills anymore but imagination.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>Remember when visiting someone's website felt like stepping into their living room? When every click revealed another piece of their personality, quirky design choices, and unique way of seeing the world?</p>\n<p>Growing up, one of the things I loved about the internet was how radically different each website was from the others.</p>\n<p>And I don't mean company websites, but personal websites.</p>\n<p>Newsletter and blog platforms like Medium, Substack, and Beehiiv didn't exist at the time. People built their websites from scratch (HTML, CSS and some JavaScript). Every pixel was crafted to reflect their thoughts and personality.</p>\n<p>Picture this: neon green text on black backgrounds, animated GIFs that served no purpose other than joy, custom cursors, and background music that auto-played (yes, we actually did that).</p>\n<p>These weren't just websites. They were digital extensions of their creators.</p>\n<p>Since they had invested time and creativity in building these digital spaces, each site became a unique fingerprint.</p>\n<p>That felt magical.</p>\n<p>You weren't just reading a post from somebody. You were accessing their \"corner of the internet\". You were getting to know them.</p>\n<blockquote>\n<p>\"Corners of the internet\" refers to specific websites, online communities, or digital spaces that are unique, niche, or offer a particular kind of experience, often one that is more personal, quirky, or less mainstream than the larger, more popular parts of the internet.</p>\n</blockquote>\n<br>\n<p>But with the rise of platforms that promise better discoverability and easier publishing, something beautiful was lost. Every page now feels like it was stamped from the same template.</p>\n<p>Don't get me wrong, these tools have democratized publishing and helped millions of people share their ideas. But in gaining convenience, we've lost personality.</p>\n<p>I often find myself reading blogs through email newsletters because it's convenient. But I miss the anticipation of visiting a website that might surprise me, where the author's personality leaked through every design choice.</p>\n<p>The web used to be weird, wonderful, and deeply personal.</p>\n<p>Now it's efficient, discoverable, and... bland.</p>\n<p>But here's the thing: I think now is the perfect time to change that.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"my-experiment-building-weird-again\">My experiment: Building weird again<a href=\"https://didierlopes.com/blog/bring-back-your-corner-of-the-internet#my-experiment-building-weird-again\" class=\"hash-link\" aria-label=\"Direct link to My experiment: Building weird again\" title=\"Direct link to My experiment: Building weird again\">​</a></h2>\n<p>I wanted an excuse to test Claude Code but didn't want to experiment on our production codebase. So I used my personal website as a playground: the perfect place to get weird.</p>\n<p>There were two pages I'd been wanting to build for months, but work always got in the way. I thought, maybe AI could help me finally make them real.</p>\n<p>Spoiler alert: <strong>It worked beautifully</strong>.</p>\n<p>Within a few hours, I had not just functional pages, but pages with personality.</p>\n<p>Here's what I built:</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"the-intelligence-page\">The Intelligence Page<a href=\"https://didierlopes.com/blog/bring-back-your-corner-of-the-internet#the-intelligence-page\" class=\"hash-link\" aria-label=\"Direct link to The Intelligence Page\" title=\"Direct link to The Intelligence Page\">​</a></h3>\n<p>Transforms my blog posts into a living, breathing network. Imagine your thoughts as nodes in a graph—each post connected to related ideas, creating a visual \"second brain\" that you can explore and navigate.</p>\n<div style=\"display:flex;flex-wrap:wrap;justify-content:center;gap:1em\"><img width=\"500\" src=\"https://didierlopes.com/blog/2025-07-02-bring-back-your-corner-of-the-internet_1.webp\"><img width=\"500\" src=\"https://didierlopes.com/blog/2025-07-02-bring-back-your-corner-of-the-internet_2.webp\"></div>\n<br>\n<ul>\n<li>But here's where it gets fun: I added Kawspeely (a Fortnite character I edited with GPT-4o) who points visitors to this graph of nodes (posts). In dark mode, it becomes Kaws Skeleton. Both wear red Crocs because... why not?</li>\n</ul>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"the-chat-page\">The Chat Page<a href=\"https://didierlopes.com/blog/bring-back-your-corner-of-the-internet#the-chat-page\" class=\"hash-link\" aria-label=\"Direct link to The Chat Page\" title=\"Direct link to The Chat Page\">​</a></h3>\n<p>Lets visitors talk to an LLM that is running on their machine through Ollama, but has access to all my blogs through RAG. It's like having a conversation with my thoughts, even when I'm not there, and all the computation happens in the user machine.</p>\n<div style=\"display:flex;flex-wrap:wrap;justify-content:center;gap:1em\"><img width=\"500\" src=\"https://didierlopes.com/blog/2025-07-02-bring-back-your-corner-of-the-internet_3.webp\"><img width=\"500\" src=\"https://didierlopes.com/blog/2025-07-02-bring-back-your-corner-of-the-internet_4.webp\"></div>\n<br>\n<ul>\n<li>The interface features a kid Goku animation that reacts to the indexing of the blogposts with manga-style effects.</li>\n<li>When you clear the chat, an eraser sweeps across the screen in light mode—or Rick's portal gun appears in dark mode.</li>\n<li>Podcast audio below explaining what is going on generated by NotebookLM.</li>\n</ul>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"why-now-is-the-perfect-time\">Why now is the perfect time<a href=\"https://didierlopes.com/blog/bring-back-your-corner-of-the-internet#why-now-is-the-perfect-time\" class=\"hash-link\" aria-label=\"Direct link to Why now is the perfect time\" title=\"Direct link to Why now is the perfect time\">​</a></h2>\n<p>This experiment made me realize something profound: the barriers that once kept us from building beautiful, personal websites have disappeared.</p>\n<p>Remember when you needed to know HTML, CSS, JavaScript, server management, and deployment? When you had to hand-code every animation and debug browser compatibility issues for hours?</p>\n<p>Those days are over.</p>\n<p>With tools like Claude Code, Replit, Lovable, and Cursor, there's no excuse not to reclaim your corner of the internet.</p>\n<p>AI can help you build the weird, wonderful website you've always imagined but never had the technical skills to create.</p>\n<p>I keep thinking about these viral tweets that perfectly capture the moment:</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-07-02-bring-back-your-corner-of-the-internet_5.webp\"></p>\n<p>The web became obsessed with conversion rates, SEO optimization, and uniform user experiences. We optimized the soul out of our digital spaces.</p>\n<p>But now, with AI as our creative partner, we can build beautiful things again.</p>\n<p><strong>The ceiling isn't technical skill, it's imagination</strong>.</p>\n<p>The question isn't \"Can I build this?\" anymore. It's \"What do I want to build?\"</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"some-corner-of-the-internet-inspo\">Some corner of the internet inspo<a href=\"https://didierlopes.com/blog/bring-back-your-corner-of-the-internet#some-corner-of-the-internet-inspo\" class=\"hash-link\" aria-label=\"Direct link to Some corner of the internet inspo\" title=\"Direct link to Some corner of the internet inspo\">​</a></h2>\n<ul>\n<li><strong>Ryo Lu from Cursor</strong>: <a href=\"https://ryo.lu/\" target=\"_blank\" rel=\"noopener noreferrer\">https://ryo.lu/</a></li>\n<li><strong>Pieter Levels</strong>: <a href=\"https://pieter.com/\" target=\"_blank\" rel=\"noopener noreferrer\">https://pieter.com/</a></li>\n<li><strong>Eva</strong>: <a href=\"https://kibty.town/\" target=\"_blank\" rel=\"noopener noreferrer\">https://kibty.town</a></li>\n<li><strong>Tyler Denk</strong>: <a href=\"https://mail.bigdeskenergy.com/\" target=\"_blank\" rel=\"noopener noreferrer\">https://mail.bigdeskenergy.com/</a></li>\n</ul>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"your-turn\">Your turn<a href=\"https://didierlopes.com/blog/bring-back-your-corner-of-the-internet#your-turn\" class=\"hash-link\" aria-label=\"Direct link to Your turn\" title=\"Direct link to Your turn\">​</a></h2>\n<p>Here's my challenge to you: <strong>build something weird</strong>.</p>\n<p>Not for your company. Not for your personal brand. Build something that makes you smile when you look at it. Something that would make teenage-you proud.</p>\n<p><strong>Getting Started</strong>:</p>\n<ol>\n<li>Pick an AI coding tool (Claude Code, Cursor, Replit, Lovable)</li>\n<li>Start with one small, strange idea</li>\n<li>Don't worry about mobile responsiveness or SEO</li>\n<li>Add something that serves no purpose other than joy</li>\n<li>Deploy it and share it</li>\n</ol>\n<p>The web is waiting for your weird.</p>\n<p>Let's make it beautiful again.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/bring-back-your-corner-of-the-internet",
            "title": "Bring back your corner of the internet",
            "summary": "The web has become bland and uniform. It's time to bring back the weird, wonderful, and deeply personal websites that once made the internet magical. With AI, the limit aren't skills anymore but imagination.",
            "date_modified": "2025-07-02T00:00:00.000Z",
            "tags": [
                "personal-websites",
                "blogging",
                "internet-culture",
                "creativity",
                "ai",
                "development",
                "web-design"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/humanoid-robots-are-a-waste-of-money",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-06-25-humanoid-robots-are-a-waste-of-money.webp\"></p>\n<p>Why the obsession around humanoid robots?</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>I have a BSc. in Electrical and Computer Engineering and an MSc. in Control Systems. My O-1 Visa was obtained as an expert in automated systems. Robotics was one of the fields I studied - with projects ranging from a maze runner to a car wash station, warehouse storage optimization, and using Kuka robot arms for precision automation.</p>\n<p>So I don't say this lightly, especially as a techno-optimist who's constantly excited and curious about new breakthroughs.</p>\n<p><strong>But: Humanoid robots are a distraction.</strong></p>\n<p>The innovation that matters isn't our form - it's our intelligence.</p>\n<p>Our hands? A compromise.</p>\n<p>Our bodies? A constraint.</p>\n<p>We've just learned to live with them.</p>\n<p><strong>The magic of human capability lies in our minds, not the awkward mechanics we've evolved to navigate the world.</strong></p>\n<p>If we're designing automation from scratch, why copy the worst part of the package?</p>\n<p>Look at Waymo. If all you need is \"take me to X\", why build a steering wheel, pedals, or even a dashboard?So why the obsession with making robots look like us?</p>\n<p>A lot of it has nothing to do with performance - and everything to do with us.</p>\n<p><strong>Familiarity. Comfort.</strong></p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-06-25-humanoid-robots-are-a-waste-of-money_1.webp\"><em style=\"font-size:0.9em\">Note: Waymo uses window wipers, not because it is required to function. But for familiarity.</em></p>\n<p><strong>Maybe even power.</strong></p>\n<p>The fantasy isn't that a humanoid robot does chores - it's that it lives among us, obeys us, and asks nothing back. That's Westworld territory.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-06-25-humanoid-robots-are-a-waste-of-money_2.webp\"></p>\n<p>And it raises questions less about engineering, and more about ethics.</p>\n<p>The same logic applies to home and industrial automation: the goal shouldn't be to replicate humans. It should be to outperform them.</p>\n<p>A humanoid robot that walks around your house to do dishes, fold laundry, and make your bed? That's a Jack-of-all-trades, master of none - expensive, slow, and space-hogging.</p>\n<p>Meanwhile, we could build five hyper-specialized machines, each optimized for one task, that outperform any humanoid in speed, precision, and efficiency.</p>\n<p>And in doing so, we'd probably <strong>reinvent dishwashers, laundry machines, and home workflows entirely.</strong></p>\n<p>The Tesla factory doesn't rely on humanoid robots.</p>\n<div class=\"flex place-items-center justify-center items-center rounded-sm mx-auto\"><iframe src=\"https://www.youtube.com/embed/blW-Fa4a10g?si=q7mXIbRsz5PGCD5n\" width=\"800\" height=\"400\"></iframe></div>\n<br>\n<p>It relies on arms, conveyors, and tightly choreographed systems. Humans are still there, but mostly when:</p>\n<ul>\n<li>Accountability is needed for edge-case quality issues</li>\n<li>The task is too small or uneconomical to automate yet</li>\n<li>The task is ad-hoc or non-repeatable</li>\n</ul>\n<p>That's not a vote of confidence for humanlike form - it's a sign of where automation hasn't yet reached.</p>\n<p><em>\"But what if a humanoid could vacuum and mop?\"</em></p>\n<p>We already have robots that do that, because they're purpose-built. Not because they need knees.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-06-25-humanoid-robots-are-a-waste-of-money_3.webp\"><em style=\"font-size:0.9em\">Note: People on X swear by <a href=\"https://maticrobots.com/\" target=\"_blank\" rel=\"noopener noreferrer\">Matic Robot</a>.</em></p>\n<p>The future of automation isn't human-shaped.</p>\n<p><strong>It's task-shaped.</strong></p>\n<p><strong>Context-aware.</strong></p>\n<p><strong>Invisible.</strong></p>\n<p>General-purpose humanoid robots are a sci-fi fantasy chasing the wrong abstraction.</p>\n<p>If you want real-world impact, stop trying to clone us, and <strong>start designing systems that reinvent jobs to be done</strong>.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/humanoid-robots-are-a-waste-of-money",
            "title": "Humanoid robots are a waste of money",
            "summary": "Why the obsession around humanoid robots?",
            "date_modified": "2025-06-25T00:00:00.000Z",
            "tags": [
                "robotics",
                "automation",
                "humanoid-robots",
                "ai",
                "future-of-tech",
                "tesla"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/i-cant-believe-i-recommended-replit-instead-of-cursor",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-06-20-i-cant-believe-i-recommended-replit-instead-of-cursor.webp\"></p>\n<p>Replit is the ultimate coding environment for non-coders.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>Replit is a monster brewing.</p>\n<p>It took me some time to realize this.</p>\n<p>Mostly because I don't use it myself and I don't personally know anyone who does.</p>\n<p>But last weekend, I ended up pitching it to a friend of mine so much that he ended up subscribing to it.</p>\n<p>Let me explain:</p>\n<ul>\n<li>Why I started pitching Cursor to my friend, but ended up pitching Replit instead</li>\n<li>How Replit can save him thousands of dollars a month</li>\n<li>Why I believe Replit is the future of software development</li>\n</ul>\n<p>The context: I have a friend who used to be an investment banker and has been working on a website for a paid community focused on stock recommendations.</p>\n<p>The features he needs:</p>\n<ul>\n<li>A marketing website for his personal brand</li>\n<li>Payment processing (via Stripe)</li>\n<li>A member-only area to access quarterly reports and financial data</li>\n<li>Newsletter subscriptions (via a third-party tool)</li>\n</ul>\n<p>Relatively simple.</p>\n<p>But he's never coded before, so building this isn't exactly straightforward.</p>\n<p>So he outsourced it.</p>\n<p>I started talking to him about how much I'm able to develop these days using AI, even with all the daily meetings I have, compared to what I was able to do before.</p>\n<p>When he came over to my place, I showed him how I use Cursor to code.</p>\n<p>He actually brought his laptop so I could walk him through it. So I downloaded Cursor for him.</p>\n<p>Downloading Cursor was the easy part. Over the next hour or so, I had to:</p>\n<ul>\n<li>Run git pull on his repo</li>\n<li>Explain what's stored locally vs in the cloud</li>\n<li>Explain branches</li>\n<li>Explain environment variables and API keys so the app could run</li>\n<li>Explain how the app deployment works</li>\n</ul>\n<p>Bear in mind: this was his first time touching a command line or using Git.</p>\n<p>I was able to run his code locally and use AI to make a few changes. But it's still quite far from being a \"production-ready\" setup.</p>\n<p>Sure, he could learn it - but it takes time. And every time there's a hiccup, it's much harder for him to debug, especially since it's all happening locally.</p>\n<p><strong>That's when Replit entered the room.</strong></p>\n<p>And it hit me.</p>\n<p>This is <strong>exactly</strong> the problem Replit is solving.</p>\n<p>For users who don't want to run anything locally. Who just want their code as close to production as possible. Who don't care about Git branches, they just want to preview changes and deploy with the least friction. Even on the go.</p>\n<p>It's not just about POCs. It's about apps where the stakes aren't super high, which, frankly, describes the vast majority of applications.</p>\n<p>Especially the ones non-developers want to build.</p>\n<p>In my opinion, <strong>Replit is the ultimate coding environment for non-coders</strong> - but one that still provides a full coding interface for when they do want to get their hands dirty (especially as AI continues to improve).</p>\n<p>Ultimately, I can see Replit Agent becoming Replit. Maybe even hiding the IDE entirely by default.</p>\n<p>And I believe this will happen because of the audience Replit is building for.</p>\n<p>Now, my friend is just waiting for his outsourced developer to finish the last sprint of work. After that, he's switching to Replit.</p>\n<p>It'll completely replace UpWork for him. He'll no longer be limited by someone else's availability or quality - only by his own time and how well the model performs.</p>\n<p>Instead of messaging a freelancer on UpWork, waiting hours for a response, checking the deployed version, asking for a minor tweak, waiting again, etc...</p>\n<p>He'll just open Replit on his phone, ask the Agent to make the change, preview it seconds later, ask for an adjustment, preview again - and deploy when ready. Even better now with a tighter <a href=\"https://x.com/Replit/status/1932463041930760580\" target=\"_blank\" rel=\"noopener noreferrer\">design to production integration</a>.</p>\n<p>I've been a fan of Amjad for a long time.</p>\n<p>But today I became a true fan of Replit.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/i-cant-believe-i-recommended-replit-instead-of-cursor",
            "title": "I can't believe I recommended Replit instead of Cursor",
            "summary": "Replit is the ultimate coding environment for non-coders",
            "date_modified": "2025-06-20T00:00:00.000Z",
            "tags": [
                "replit",
                "cursor",
                "ai",
                "development-environment",
                "cloud-ide",
                "no-code",
                "software-development",
                "entrepreneurship"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/my-feelings-about-ai-companions",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-06-15-my-feelings-about-ai-companions.webp\"></p>\n<p>It's no longer a matter of IF, but a matter of WHEN. AI companions are coming.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>Lately, I've been thinking more and more about AI companions.</p>\n<p>Mass adoption will take time, but their emergence feels inevitable.</p>\n<p><a href=\"https://www.linkedin.com/in/dsiroker\" target=\"_blank\" rel=\"noopener noreferrer\">Dan</a>'s tagline - \"<em>everything you've seen, said, and heard</em>\" - is actually a pretty accurate depiction of where we're headed.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-06-15-my-feelings-about-ai-companions_1.webp\"></p>\n<p>Does that excite me?</p>\n<p><strong>Yes</strong> and <strong>no</strong>.</p>\n<p>Yes, because at a fundamental level, humans are evolving.</p>\n<p>This is the next phase of our evolution - being enhanced by technology.</p>\n<p>We already are, with laptops, phones, and more.</p>\n<p>But this feels like a deeper shift.</p>\n<p>Now, we have technology capable of processing vast amounts of data and generating something meaningful from it:</p>\n<ul>\n<li>Summarizing meeting notes</li>\n<li>Chatting with me to help understand a topic I just heard in class</li>\n<li>Reviewing my sales pitch and offering ways I could have improved</li>\n</ul>\n<p>That part excites me: it will make life feel more fluid.</p>\n<p>Tasks that used to take hours will take minutes.</p>\n<p>Tasks that took minutes will take seconds.</p>\n<p>Even something as simple as finding the name of that cafe someone once recommended becomes instant.</p>\n<p><strong>But with that fluidity, we're losing randomness, spontaneity. The messiness that makes us human.</strong></p>\n<p>The fact that we're all just trying to figure things out.</p>\n<p><strong>What happens when you can't even choose between pizza or a burger because an algorithm tells you that eating chicken and rice will extend your life span by 5 minutes?</strong></p>\n<p>What happens when there's so much human data that everything becomes algorithmic?</p>\n<p>And instead of making irrational choices, the kind that make us human, you start choosing only what optimizes your body.</p>\n<p>At some point, it may start to feel like we're living in the movie \"In Time\", with a clock ticking down our remaining time on Earth.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-06-15-my-feelings-about-ai-companions_2.webp\"></p>\n<p>But it's not just that.</p>\n<p>Think about relationships.</p>\n<p>My parents met in school, in the same small town. They're still together.</p>\n<p>I met my wife on a dating app. I had access to a much larger pool of potential partners than my parents ever did. But I didn't have data convincing me she was \"the one.\" We had a first dinner. I got to know her, from her.</p>\n<p>What happens when everyone has an AI companion, and you can access a trailer-like preview of someone you just met?</p>\n<p>What happens when an algorithm tells you that you and X are 99.999% likely to be soulmates and live happily ever after?</p>\n<p>Where's the thrill?</p>\n<p>When life becomes so deterministic that it feels like you're simply executing a prewritten script - just following your destiny.</p>\n<p>At least for now, it still feels like we're in control.</p>\n<p>Maybe one day, it won't.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/my-feelings-about-ai-companions",
            "title": "My feelings about AI companions",
            "summary": "It's no longer a matter of IF, but a matter of WHEN. AI companions are coming.",
            "date_modified": "2025-06-15T00:00:00.000Z",
            "tags": [
                "ai",
                "ai-companions",
                "future",
                "technology",
                "humanity",
                "philosophy",
                "relationships",
                "singularity"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/i-just-tested-dia-browser-and-i-have-thoughts",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-06-12-i-just-tested-dia-browser-and-i-have-thoughts.webp\"></p>\n<p>Thoughts on Dia browser's AI integration, exploring its similarities with OpenBB Workspace and the role of AI assistants in finance tools.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>So I just tested the Dia browser (available today for Arc users).</p>\n<p>I actually like the idea.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-06-12-i-just-tested-dia-browser-and-i-have-thoughts_1.webp\"></p>\n<p>This is actually similar to the insight we had when we started incorporating AI natively to the OpenBB Workspace - that chatting interface is a path for human interact.</p>\n<p>But often it isn't.</p>\n<p>Often you want the human in the driving seat, and an AI assistant right there.</p>\n<p>It's about the context this AI assistant has access to and what it can do.</p>\n<p>It's about having AI having access to the same tools that you have, and allowing you to streamline your workflows.</p>\n<p>When putting OpenBB Workspace next to Dia it's easy to understand that the concept is similar.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-06-12-i-just-tested-dia-browser-and-i-have-thoughts_2.webp\"></p>\n<p>The main difference, for me, is that our workspace provides a more tight-loop control over your data and interactions. Whereas Dia has a more open nature.</p>\n<p>This is a feature, not a bug. We want the AI agent to focus on data that firms want to give their users access to, and often that means that not all data is fair game.</p>\n<p>One of the things that I wish they would do (as a current Arc user) is bring the left sidebar back.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-06-12-i-just-tested-dia-browser-and-i-have-thoughts_3.webp\"></p>\n<p>In a way, how we structure the workspace - which was actually inspired by Arc :)</p>\n<p>We've come full circle on this one.</p>\n<hr>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"slight-note-update\">Slight note update<a href=\"https://didierlopes.com/blog/i-just-tested-dia-browser-and-i-have-thoughts#slight-note-update\" class=\"hash-link\" aria-label=\"Direct link to Slight note update\" title=\"Direct link to Slight note update\">​</a></h2>\n<p>Although I like the browser, I haven't adopted it yet.</p>\n<p>Why?</p>\n<p>Well Peer said it perfectly <a href=\"https://x.com/peer_rich/status/1936419182423281699\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-06-12-i-just-tested-dia-browser-and-i-have-thoughts_4.webp\"></p>\n<p>It's about whether the company is still around in 1 year or not. Particularly as they are over 100 people and still hiring - without a proven business model, AFAIK?</p>\n<p>The irony here is that - had they open source Arc, then I would have trust them to use Dia because if the company ceased to exist, someone would be able to take over the project.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/i-just-tested-dia-browser-and-i-have-thoughts",
            "title": "I just tested Dia browser, and I have thoughts",
            "summary": "Thoughts on Dia browser's AI integration, exploring its similarities with OpenBB Workspace and the role of AI assistants in finance tools.",
            "date_modified": "2025-06-12T00:00:00.000Z",
            "tags": [
                "dia-browser",
                "arc-browser",
                "ai",
                "ai-assistant",
                "openbb",
                "tech"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/how-i-connected-figma-to-cursor-using-mcp",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-06-10-how-i-connected-figma-to-cursor-using-mcp.webp\"></p>\n<p>A step-by-step guide on how to connect Figma to Cursor using MCP (Model-Client-Protocol), enabling seamless design-to-code workflow and improving developer productivity through direct design system integration.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>This weekend, I was - <strong>again</strong> - mind blown by technology.</p>\n<p>As I was working on OpenBB, and needed to copy the style from the Figma mockups - I stumbled upon Figma MCP.</p>\n<p>Here's what I said on the <a href=\"https://www.linkedin.com/posts/didier-lopes_i-still-cant-believe-this-i-was-deep-into-activity-7337573643431944192-f9-L?utm_source=share&amp;utm_medium=member_desktop&amp;rcm=ACoAABub6aIBaA7HieEI5VizHglQPohLA_Wptag\" target=\"_blank\" rel=\"noreferrer\">LinkedIn post</a>.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-06-10-how-i-connected-figma-to-cursor-using-mcp_1.webp\"></p>\n<p>And this is the video that I added to the post:</p>\n<div class=\"flex place-items-center justify-center items-center rounded-sm mx-auto\"><iframe src=\"https://www.youtube.com/embed/UwC_pbEnN3U?si=w15gGna5j1OhgPFp\" width=\"800\" height=\"400\"></iframe></div>\n<br>\n<p>So, in this short post, I'm going to tell you how you can do the same in a couple of steps.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"enabling-mcp-server-on-figma\">Enabling MCP Server on Figma<a href=\"https://didierlopes.com/blog/how-i-connected-figma-to-cursor-using-mcp#enabling-mcp-server-on-figma\" class=\"hash-link\" aria-label=\"Direct link to Enabling MCP Server on Figma\" title=\"Direct link to Enabling MCP Server on Figma\">​</a></h2>\n<ol>\n<li>\n<p>Make sure you are using Figma desktop app.</p>\n</li>\n<li>\n<p>Go into \"Dev Mode\" on the bottom toolbar.</p>\n</li>\n</ol>\n<br>\n<p align=\"center\"><img width=\"400\" src=\"https://didierlopes.com/blog/2025-06-10-how-i-connected-figma-to-cursor-using-mcp_2.webp\"></p>\n<ol start=\"3\">\n<li>Enable MCP Server.</li>\n</ol>\n<br>\n<p align=\"center\"><img width=\"400\" src=\"https://didierlopes.com/blog/2025-06-10-how-i-connected-figma-to-cursor-using-mcp_3.webp\"></p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"set-up-mcp-client-cursor\">Set up MCP client (Cursor)<a href=\"https://didierlopes.com/blog/how-i-connected-figma-to-cursor-using-mcp#set-up-mcp-client-cursor\" class=\"hash-link\" aria-label=\"Direct link to Set up MCP client (Cursor)\" title=\"Direct link to Set up MCP client (Cursor)\">​</a></h2>\n<ol>\n<li>Open Cursor Settings</li>\n</ol>\n<br>\n<p align=\"center\"><img width=\"500\" src=\"https://didierlopes.com/blog/2025-06-10-how-i-connected-figma-to-cursor-using-mcp_4.webp\"></p>\n<ol start=\"2\">\n<li>Add a new MCP server</li>\n</ol>\n<br>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-06-10-how-i-connected-figma-to-cursor-using-mcp_5.webp\"></p>\n<p>When clicking on \"Add Custom MCP\", copy paste the following block of code:</p>\n<div class=\"language-json codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-json codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">{</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\"></span><span class=\"token property\">\"mcpServers\"</span><span class=\"token operator\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">{</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">  </span><span class=\"token property\">\"Figma\"</span><span class=\"token operator\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">{</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    </span><span class=\"token property\">\"url\"</span><span class=\"token operator\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"http://127.0.0.1:3845/sse\"</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">  </span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">}</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">}</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">}</span><br></span></code></pre></div></div>\n<p>Then save it, like this:</p>\n<p align=\"center\"><img width=\"400\" src=\"https://didierlopes.com/blog/2025-06-10-how-i-connected-figma-to-cursor-using-mcp_6.webp\"></p>\n<p>Once you close that file, you'll see that Cursor Settings MCP tab now displays \"Loading tools\":</p>\n<p align=\"center\"><img width=\"700\" src=\"https://didierlopes.com/blog/2025-06-10-how-i-connected-figma-to-cursor-using-mcp_7.webp\"></p>\n<p>After a few seconds you can toggle the Figma MCP and you should be able to see a few tools.</p>\n<p align=\"center\"><img width=\"700\" src=\"https://didierlopes.com/blog/2025-06-10-how-i-connected-figma-to-cursor-using-mcp_8.webp\"></p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"usage\">Usage<a href=\"https://didierlopes.com/blog/how-i-connected-figma-to-cursor-using-mcp#usage\" class=\"hash-link\" aria-label=\"Direct link to Usage\" title=\"Direct link to Usage\">​</a></h2>\n<p>The usage is very simple.</p>\n<p>You just need to select the layout you want to pass to Cursor on Figma, and then right click on it and select \"Copy link to selection\".</p>\n<p align=\"center\"><img width=\"400\" src=\"https://didierlopes.com/blog/2025-06-10-how-i-connected-figma-to-cursor-using-mcp_9.webp\"></p>\n<p>Then you paste that link to Cursor and you prompt accordingly.</p>\n<p align=\"center\"><img width=\"400\" src=\"https://didierlopes.com/blog/2025-06-10-how-i-connected-figma-to-cursor-using-mcp_10.webp\"></p>\n<p>Note: I recommend to be explicit with the model to utilize MCP.</p>\n<p>That's it. I hope this is helpful.</p>\n<p>Happy hacking.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/how-i-connected-figma-to-cursor-using-mcp",
            "title": "How I connected Figma to Cursor using MCP",
            "summary": "A step-by-step guide on how to connect Figma to Cursor using MCP (Model-Client-Protocol), enabling seamless design-to-code workflow and improving developer productivity through direct design system integration.",
            "date_modified": "2025-06-10T00:00:00.000Z",
            "tags": [
                "figma",
                "cursor",
                "mcp",
                "developer-tools",
                "tutorial",
                "integration",
                "design-to-code",
                "productivity",
                "development-workflow"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/not-your-typical-data-vendor",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-06-01-not-your-typical-data-vendor.webp\"></p>\n<p>This post explores Financial Datasets, a data vendor focused on top-tier developer experience and data quality, with an API built for AI agents.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>There are hundreds, maybe even thousands, of financial data vendors out there.</p>\n<p>Each with its own flavor of data quality, coverage, automation, business model, developer experience, and pricing.</p>\n<p>But in such a crowded space, standing out means doing at least one thing 10x better than the rest.</p>\n<p>Financial Datasets does two:</p>\n<ol>\n<li>\n<p><strong>Best-in-class developer experience</strong>.</p>\n<p>The API is simple, clean, and fast—not just for humans, but purpose-built for AI agents. As the founder puts it: \"Our API is designed for AI financial agents (...)\"</p>\n</li>\n<li>\n<p><strong>Obsessive focus on data quality</strong>.</p>\n<p>The founder personally digs into SEC filings to understand discrepancies between their numbers and those from other vendors. That level of care isn't common. It shows.</p>\n</li>\n</ol>\n<br>\n<p>Given all that (and the fact that I play football ⚽️ with the author), I decided to build an OpenBB app powered by this API so you can try it out yourself - and see what data is available.</p>\n<div style=\"display:flex;flex-wrap:wrap;justify-content:center;gap:1em\"><img width=\"500\" src=\"https://didierlopes.com/blog/2025-06-01-not-your-typical-data-vendor_2.webp\"><img width=\"500\" src=\"https://didierlopes.com/blog/2025-06-01-not-your-typical-data-vendor_3.webp\"></div>\n<br>\n<p>Two steps:</p>\n<ol>\n<li>Login into <a href=\"https://pro.openbb.co/\" target=\"_blank\" rel=\"noopener noreferrer\">https://pro.openbb.co</a></li>\n<li>Add the app with this link: <a href=\"https://pro.openbb.co/app?modal=connect-backend&amp;name=Financial%20Datasets&amp;url=https://financial-datasets-openbb.fly.dev\" target=\"_blank\" rel=\"noopener noreferrer\">https://pro.openbb.co/app?modal=connect-backend&amp;name=Financial%20Datasets&amp;url=https://financial-datasets-openbb.fly.dev</a></li>\n</ol>\n<br>\n<p>This is the app that you should expect:</p>\n<p align=\"center\"><img width=\"300\" src=\"https://didierlopes.com/blog/2025-06-01-not-your-typical-data-vendor_1.webp\"></p>\n<p>It will be limited to a few tickers that the creator has made accessible for free.</p>\n<p>More information you can check it out at <a href=\"https://www.financialdatasets.ai/\" target=\"_blank\" rel=\"noopener noreferrer\">https://www.financialdatasets.ai/</a>.</p>\n<p>Or if you have an API key, you can adapt the source code to support more tickers <a href=\"https://github.com/virattt/openbb-financialdatasets-backend\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/not-your-typical-data-vendor",
            "title": "Not your typical data vendor",
            "summary": "This post explores Financial Datasets, a data vendor focused on top-tier developer experience and data quality, with an API built for AI agents.",
            "date_modified": "2025-06-01T00:00:00.000Z",
            "tags": [
                "financial-data",
                "api",
                "developer-experience",
                "ai",
                "ai-agents",
                "openbb",
                "data-quality",
                "financial-datasets",
                "sec-filings"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/openbb-is-underrated",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-05-28-openbb-is-underrated.webp\"></p>\n<p>OpenBB isn't just software - it's foundational infrastructure that lets firms shape their own financial workspace, moving beyond one-size-fits-all solutions toward modularity and extensibility.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>Something I’ve noticed lately, many people I speak with who do know about OpenBB say the same thing, almost verbatim:</p>\n<ul>\n<li>\n<p>\"You guys are so underrated.\"</p>\n</li>\n<li>\n<p>\"I was in a room with CIOs and they hadn’t yet heard about OpenBB.\"</p>\n</li>\n<li>\n<p>\"I wonder why more people don’t use OpenBB.\"</p>\n</li>\n</ul>\n<br>\n<p>They say it with a mix of <strong>surprise and respect</strong> - because once they’ve seen it in action, they get it.</p>\n<p>New products take time. New ideas, especially in finance, take even longer. The industry doesn't exactly sprint towards innovation.</p>\n<p>But we’re not waiting for permission.</p>\n<p>We are quietly redefining what a modern financial infrastructure looks like.</p>\n<p>It’s not about making a nicer desktop app. It’s not about putting a glossy skin on legacy workflows. We’re not trying to mimic old tools - we’re playing our own game. Executing on our own vision.</p>\n<p><strong>OpenBB is foundational.</strong></p>\n<p>We built it from scratch because we had no choice. Nothing existed that let us move fast, integrate deeply, and give real control to the end user. So we built it. And in doing so, we gave firms the ability to do the same.</p>\n<p><strong>OpenBB isn’t just software</strong>. It’s infrastructure. It’s a flexible, programmable foundation that lets firms <strong>shape their own financial workspace</strong> - aligned with their needs, integrated with their tools, and adaptable as they evolve.</p>\n<p>That’s where we fit.</p>\n<p>And now, with the launch of apps, users are even closer to value. Apps cut through noise. They bring workflows into focus. They get insights into hands faster. This isn’t about flashy features - it’s about practical, daily utility that compounds.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-05-28-openbb-is-underrated.webp\"></p>\n<p>OpenBB meets users wherever they are. We empower individuals to work smarter and faster. We enable researchers to glide from raw data to actionable insight. And we give firms the building blocks to create infrastructure that reflects how they think, how they work - not how outdated systems expect them to conform.</p>\n<p><em>The Terminalist</em> captured this perfectly in their <a href=\"https://theterminalist.substack.com/?utm_source=navbar&amp;utm_medium=web\" target=\"_blank\" rel=\"noreferrer\">latest post</a>:</p>\n<p align=\"center\"><img width=\"900\" src=\"https://didierlopes.com/blog/2025-05-28-openbb-is-underrated_1.webp\"><img width=\"900\" src=\"https://didierlopes.com/blog/2025-05-28-openbb-is-underrated_2.webp\"></p>\n<p>What other company fits this description better than us?</p>\n<p>We aren’t clinging to old paradigms. We are betting on modularity, composability, and extensibility - the principles that will define the next generation of fintech.</p>\n<p>The Terminalist calls it the rise of post-terminalism.</p>\n<p>We see it as <strong>the fall of the illusion that one-size-fits-all</strong>.</p>\n<p>People don’t always appreciate what we’ve built - until they do. And when they see it - when they feel the control, the extensibility, the raw power, it’s hard to go back.</p>\n<p>The infrastructure is already here.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/openbb-is-underrated",
            "title": "OpenBB is underrated",
            "summary": "OpenBB isn't just software - it's foundational infrastructure that lets firms shape their own financial workspace, moving beyond one-size-fits-all solutions toward modularity and extensibility.",
            "date_modified": "2025-05-28T00:00:00.000Z",
            "tags": [
                "fintech",
                "infrastructure",
                "financial-analysis",
                "open-source",
                "openbb",
                "modularity",
                "workflows",
                "post-terminalism",
                "extensibility"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/sec-filings-to-uncover-and-track-financial-and-economic-indicators",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-05-22-sec-filings-to-uncover-and-track-financial-and-economic-indicators.webp\"></p>\n<p>This post explores how SEC filings can be used to uncover and track financial and economic indicators. It showcases an open-source OpenBB app that visualizes this data, providing valuable insights for investment research and market trend analysis.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>A few days ago, <a href=\"https://www.linkedin.com/in/justinlokos/\" target=\"_blank\" rel=\"noopener noreferrer\">Justin Lokos</a> shared a fascinating GitHub repository maintained by <a href=\"https://www.linkedin.com/in/johngfriedman/\" target=\"_blank\" rel=\"noopener noreferrer\">John Friedman</a> that really caught my attention.</p>\n<p>This repository analyzes SEC filings to uncover and track financial and economic indicators across a wide range of sectors.</p>\n<p>It can be found <a href=\"https://github.com/john-friedman/datamule-indicators\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<p>It processes topic mentions from regulatory filings and turns them into standardized, sector-level metrics that are updated daily - making it a powerful tool for identifying trends across the economy.</p>\n<p>I found the data so compelling that I built and hosted an OpenBB app around it.</p>\n<div style=\"display:flex;flex-wrap:wrap;justify-content:center;gap:1em\"><img width=\"500\" src=\"https://didierlopes.com/blog/2025-05-22-sec-filings-to-uncover-and-track-financial-and-economic-indicators_1.webp\"><img width=\"500\" src=\"https://didierlopes.com/blog/2025-05-22-sec-filings-to-uncover-and-track-financial-and-economic-indicators_2.webp\"></div>\n<br>\n<p>The app offers a wide range of indexes across key domains, including DEI and ESG in Governance; Tariffs and Supply Chain in Trade; Layoffs in Employment; Outsourcing and Supplier Concentration in Market Dynamics; Consumer Confidence in Consumer Sentiment; Space and Nuclear in Technology; Political Stability in International; IPO in Corporate Finance; Health Research, Health, and Pandemic in Health; various indexes in Resources such as Explosive Materials, Metals, Semiconductor Materials, Propellant Components, Raw Materials, Electronic Components, and Chemicals; and Military Equipment, Terrorism, and War in Military &amp; Security</p>\n<p>And then I made it available to everyone.</p>\n<p align=\"center\"><img width=\"300\" src=\"https://didierlopes.com/blog/2025-05-22-sec-filings-to-uncover-and-track-financial-and-economic-indicators_3.webp\"></p>\n<p>In fact, I <a href=\"https://www.linkedin.com/posts/didier-lopes_a-few-days-ago-justin-lokos-shared-a-fascinating-activity-7332437330659549185-4jVk?utm_source=share&amp;utm_medium=member_desktop&amp;rcm=ACoAABub6aIBaA7HieEI5VizHglQPohLA_Wptag\" target=\"_blank\" rel=\"noopener noreferrer\">shared this on LinkedIn</a> and asked people interested on the app to comment and the post got close to 20k impressions.</p>\n<p align=\"center\"><img width=\"400\" src=\"https://didierlopes.com/blog/2025-05-22-sec-filings-to-uncover-and-track-financial-and-economic-indicators_4.webp\"></p>\n<p>My friend <a href=\"https://www.linkedin.com/in/ca%C3%ADque-cober-117bbb1ab/\" target=\"_blank\" rel=\"noopener noreferrer\">Caique</a> does this often and has seen a lot of people asking for the apps from OpenBB.</p>\n<p>And here's the template DM I sent to 100+ people interested.</p>\n<blockquote>\n<p>Hey,</p>\n<br>\n<p>Sending you a message based on your comment in the post!</p>\n<br>\n<ol>\n<li>Go to <a href=\"https://pro.openbb.co/\" target=\"_blank\" rel=\"noopener noreferrer\">https://pro.openbb.co/</a> and make sure that you have an account - it's free.</li>\n</ol>\n<br>\n<ol start=\"2\">\n<li>Then go to this link: <a href=\"https://pro.openbb.co/app?modal=connect-backend&amp;name=Datamule%20Indicator&amp;url=https://openbb-datamule-indicators.fly.dev\" target=\"_blank\" rel=\"noopener noreferrer\">https://pro.openbb.co/app?modal=connect-backend&amp;name=Datamule%20Indicator&amp;url=https://openbb-datamule-indicators.fly.dev</a></li>\n</ol>\n<br>\n<p>That should populate a new backend on OpenBB where:</p>\n<br>\n<ul>\n<li>Name: Datamule Indicator</li>\n<li>URL: <a href=\"https://openbb-datamule-indicators.fly.dev/\" target=\"_blank\" rel=\"noopener noreferrer\">https://openbb-datamule-indicators.fly.dev</a></li>\n</ul>\n<br>\n<ol start=\"3\">\n<li>On the \"Apps\" tab, click on the \"Financial and Economic Indicators\" - that should open a dashboard with all the data in one place.</li>\n</ol>\n<br>\n<p>All the data should be ready to be interacted with OpenBB Copilot out-of-the-box.</p>\n<br>\n<p>If you have any questions ping me!</p>\n</blockquote>\n<br>\n<p>Also, if you want to see how I built this app - the full code is open source here: <a href=\"https://github.com/DidierRLopes/openbb-datamule-indicators\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/DidierRLopes/openbb-datamule-indicators</a>.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/sec-filings-to-uncover-and-track-financial-and-economic-indicators",
            "title": "SEC filings to uncover and track financial and economic indicators",
            "summary": "This post explores how SEC filings can be used to uncover and track financial and economic indicators. It showcases an open-source OpenBB app that visualizes this data, providing valuable insights for investment research and market trend analysis.",
            "date_modified": "2025-05-22T00:00:00.000Z",
            "tags": [
                "sec-filings",
                "financial-indicators",
                "economic-indicators",
                "openbb",
                "data-analysis",
                "open-source",
                "investment-research",
                "market-trends",
                "dashboard"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/introducing-openbb-apps-tailored-by-users-for-optimized-workflows",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-05-01-introducing-openbb-apps-tailored-by-users-for-optimized-workflows.webp\"></p>\n<p>OpenBB Apps introduces a customizable platform where financial organizations can build tailored workflow solutions with dashboard templates, data widgets, and AI agents - putting firms in complete control of their data and tech stack.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p><em>\"Be in control. Be free\"</em> was something our lead investor posted a few weeks ago.</p>\n<p>This is a great representation of the direction the financial industry is taking—to a place where firms are in control of their data and tech stack. Fully.</p>\n<p>Without the vendor lock-in. Without being limited by their vendor's data/technology, or being stuck in siloed systems and workflows.</p>\n<p>Paraphrasing an industry leader (CIO at $40 bn AUM Investment Firm) that I heard at a conference recently:</p>\n<blockquote>\n<p><em>There are a lot of nuances in our workflows, and it's hard — or even impossible — for a third-party vendor to nail our workflows fully.</em></p>\n</blockquote>\n<p>At OpenBB, we believe there's no one-size-fits-all and that firms should be able to own their workflows. End-to-end. From the proprietary data they own and the AI model they choose, to the way these two work together. While we provide the infrastructure and the interface layer, the goal is for financial organizations to <strong>build custom solutions</strong> on top of it.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"how\">How?<a href=\"https://didierlopes.com/blog/introducing-openbb-apps-tailored-by-users-for-optimized-workflows#how\" class=\"hash-link\" aria-label=\"Direct link to How?\" title=\"Direct link to How?\">​</a></h2>\n<p>By integrating their data, choosing how to display it, setting up custom dashboards, and combining all of this with their preferred AI agents. Ultimately, OpenBB enables a streamlined analysis workflow that will save your team's time and your firm's money.</p>\n<p>And that's why, today, we are <strong>introducing the concept of Apps</strong> on OpenBB.</p>\n<p>Built for specific use cases, these apps consist of a dashboard template that can include custom data widgets, AI agents, and pre-saved prompts — all carefully set up by each firm to improve their specific analysis work.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-05-01-introducing-openbb-apps-tailored-by-users-for-optimized-workflows_1.webp\"></p>\n<p>This future has been coming for some time, and this time has arrived.</p>\n<p>We have been building some apps as examples and have also been helping enterprise customers and individual users build their own, and while it's still early stages, we're amazed by the results.</p>\n<p>Here are some exciting apps (and where you can find them) that you can run on OpenBB today:</p>\n<ul>\n<li>\n<p>Portfolio Risk Management and DTCC trades - built for demo purposes by our team and available <a href=\"https://github.com/OpenBB-finance/backend-examples-for-openbb-workspace/tree/main/demo-apps/demo-risk\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n</li>\n<li>\n<p>FOMC, FRED, BLS, IMF - built for demo purposes by our team and available through our <a href=\"https://docs.openbb.co/workspace/platform-installer\" target=\"_blank\" rel=\"noopener noreferrer\">open source Platform</a></p>\n</li>\n<li>\n<p>Congressional data and Executive orders - built for demo purposes by our team and available <a href=\"https://github.com/andrewkenreich/congress\" target=\"_blank\" rel=\"noopener noreferrer\">here</a></p>\n</li>\n<li>\n<p>Crypto - built by user Matt Maximo and available <a href=\"https://github.com/MattMaximo/CryptoBB\" target=\"_blank\" rel=\"noopener noreferrer\">here</a></p>\n</li>\n<li>\n<p>Macro - built by user Caíque Cober and available <a href=\"https://openbb.co/blog/from-excel-to-agents-rebuilding-the-macro-research-workflow-for-the-ai-era\" target=\"_blank\" rel=\"noopener noreferrer\">here</a></p>\n</li>\n<li>\n<p>and more highlighted <a href=\"https://docs.openbb.co/workspace/gallery\" target=\"_blank\" rel=\"noopener noreferrer\">here</a></p>\n</li>\n</ul>\n<p>Remember, the best part is that you can build your own.</p>\n<p>If you're looking to get started building an OpenBB App, don't forget to visit <a href=\"https://docs.openbb.co/workspace\" target=\"_blank\" rel=\"noopener noreferrer\">our Documentation</a>.</p>\n<p>If you'd like to discuss bringing OpenBB to your firm, ping me!</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/introducing-openbb-apps-tailored-by-users-for-optimized-workflows",
            "title": "Introducing OpenBB Apps, tailored by users for optimized workflows",
            "summary": "OpenBB Apps introduces a customizable platform where financial organizations can build tailored workflow solutions with dashboard templates, data widgets, and AI agents - putting firms in complete control of their data and tech stack.",
            "date_modified": "2025-05-01T00:00:00.000Z",
            "tags": [
                "openbb",
                "fintech",
                "apps",
                "app-building",
                "workflows",
                "customization",
                "financial-analysis",
                "open-source",
                "ai"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/10000-followers-later-heres-where-it-all-began",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-04-11-10000-followers-later-heres-where-it-all-began.webp\"></p>\n<p>A personal reflection on my 6-year journey to 10,000 LinkedIn followers and how sharing my work publicly led to unexpected opportunities and the creation of OpenBB.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>I crossed 10,000 followers on LinkedIn.</p>\n<p>But.</p>\n<p>It took me 6 years to get here.</p>\n<p>It's been so long, I forgot what made me start posting on LinkedIn in the first place. So in this post I'm going down that memory lane.</p>\n<p>...</p>\n<p>During my university years, all I did was pretty much attend classes during the day and then study and do homework once I got home. My weekends were pretty much the same too.</p>\n<p>My main objective was to have good grades so I could pursue anything I wanted after.</p>\n<p>It wasn't about doing something in particular; it was about having the freedom to not have to do something in particular.</p>\n<p>The freedom to pick a path.</p>\n<p>After university, I landed a role as a Firmware Engineer where I was working on GNSS receivers. (I wanted to go into self-driving cars, and this role allowed me to work on chips that were used for positioning by self-driving cars—close enough, eh?)</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-04-11-10000-followers-later-heres-where-it-all-began_1.webp\"><em style=\"font-size:0.9em\">Presenting my thesis at Imperial, where I selected the topic of \"Energy savings from an Eco-Cooperative Adaptive Cruise Control: a BEV platoon investigation\"</em></p>\n<p>During the day, I was working. But in the evenings and on weekends, I didn't have my work laptop, so there wasn't much to do.</p>\n<p>In the first few weeks of the job, I was reading books about how GNSS receivers worked (this is the best one btw: <strong>Understanding GPS principles and applications</strong>).</p>\n<p><strong>Note:</strong> GPS technology is so underrated, in my opinion—maybe one of the most impactful inventions of the 20th century. To think that 50 years ago, there wasn't a single satellite in the sky is insane. I think that one of the reasons for this is that it taken for granted because it works seamlessly in the background.</p>\n<p>Anyway... There are only so many books you can read on the topic of satellite positioning.</p>\n<p>It felt odd to have this much time where there wasn’t a goal, per se, that I could easily use to tell whether I was doing the right thing or not—unlike university, where anything that doesn’t go toward getting good grades is a distraction.</p>\n<p>Given I was interested in data, AI and self-driving cars - I decided to keep learning as I did in University, but this time there was no target that others defined for me.</p>\n<p>This time, the target was my curiosity.</p>\n<p>And I was curious about ML/AI.</p>\n<p>But everywhere I looked online was recommending Python instead of MATLAB.</p>\n<p>So I bought the <strong>Python Data Science Handbook</strong>, which would allow me to learn Python in a way that was practical.</p>\n<p>After reading the first few chapters, I started side projects based on ideas I had that would let me test my skills. More importantly, they would allow me to truly learn by getting my hands dirty.</p>\n<p>As I was reading a lot on forums and Stack Overflow (RIP 🪦), I found the community amazing. People were sharing what they were working on, solutions to the problems they had—all in the open.</p>\n<p>I loved it.</p>\n<p>During my university years, I experienced two very different environments:</p>\n<ul>\n<li>An open community at my Portuguese university, where everyone shared everything—but, in general, people didn’t care that much.</li>\n<li>A closed community at TU Delft, where no one shared anything and it was extremely competitive.</li>\n</ul>\n<p>I liked the competitiveness of TU Delft, but preferred the teamwork of the Portuguese university.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-04-11-10000-followers-later-heres-where-it-all-began_2.webp\"><em style=\"font-size:0.9em\">Picture of me in Delft, back in 2016, where I did an exchange program</em></p>\n<p>This DS/ML/AI community was that.</p>\n<p>And so in that same vein, I decided to do something that I wasn't comfortable doing, I decided to start posting on LinkedIn what I was working on.</p>\n<p>Here's that <a href=\"https://www.linkedin.com/posts/didier-lopes_didierrlopesjobanalysis-activity-6499793502912815104-xa7_?utm_source=share&amp;utm_medium=member_desktop&amp;rcm=ACoAABub6aIBaA7HieEI5VizHglQPohLA_Wptag\" target=\"_blank\" rel=\"noopener noreferrer\">first post</a> 6 years ago.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-04-11-10000-followers-later-heres-where-it-all-began_3.webp\"></p>\n<p>A bit later I <a href=\"https://www.linkedin.com/posts/didier-lopes_yesterday-while-being-on-the-gym-i-was-activity-6517111978396393472-aRoe?utm_source=share&amp;utm_medium=member_desktop&amp;rcm=ACoAABub6aIBaA7HieEI5VizHglQPohLA_Wptag\" target=\"_blank\" rel=\"noopener noreferrer\">posted about another mini project I worked on</a>:</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-04-11-10000-followers-later-heres-where-it-all-began_4.webp\"></p>\n<p>Due to these posts, I got this message in my inbox from my previous Maths teacher.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-04-11-10000-followers-later-heres-where-it-all-began_5.webp\"></p>\n<p>That message was about challenging me to help him write the <a href=\"https://github.com/DidierRLopes/UnivariateTimeSeriesForecast\" target=\"_blank\" rel=\"noopener noreferrer\">code behind his thesis</a>, which was about <em><strong>Modeling and Forecasting of Financial Time Series.</strong></em></p>\n<p>This is what ultimately led me to the financial space—and to start <a href=\"http://openbb.co/\" target=\"_blank\" rel=\"noopener noreferrer\">OpenBB</a> in my spare time.</p>\n<p>Six years in, and the only thing I regret is not starting to post earlier.</p>\n<p>I can’t think of a single negative to posting on socials.</p>\n<p>So if you’re on the fence — go to LinkedIn or X and just post what you’re working on, or how you’re thinking about something.</p>\n<p>And tell me, so I can like your post to get the ball rolling.</p>\n<p>Sharing content is a marathon.</p>\n<p>And no one will care—until they do. So the best you can do is be true to yourself and post something you would want to read.</p>\n<p>At least, that’s what I do.</p>\n<p>And what I’ll keep doing.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/10000-followers-later-heres-where-it-all-began",
            "title": "10,000 followers later, here’s where it all began",
            "summary": "A personal reflection on my 6-year journey to 10,000 LinkedIn followers and how sharing my work publicly led to unexpected opportunities and the creation of OpenBB.",
            "date_modified": "2025-04-11T00:00:00.000Z",
            "tags": [
                "career",
                "personal-story",
                "linkedin",
                "social-media",
                "build-in-public",
                "networking",
                "side-projects",
                "openbb",
                "origin-story"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/stop-building-ai-products-start-building-workflows",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-04-03-stop-building-ai-products-start-building-workflows.webp\"></p>\n<p>The secret to building defensible AI companies isn't better AI - it's better workflows. An insider's perspective on why some AI companies thrive while others will become obsolete with each new model release.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>Lately, I've been asked several times about my opinion on how better AI models are ultimately going to impact financial companies and OpenBB.</p>\n<p>If you're not an AI lab, then your product is a wrapper around an LLM.</p>\n<p>In the AI space, a lot of people use the term wrapper with a negative connotation. But not all wrappers are created equal.</p>\n<p>Being a wrapper around an LLM just means that your product is not the LLM—but the wrapper itself.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"chatting-with-your-internal-data\">Chatting with your internal data<a href=\"https://didierlopes.com/blog/stop-building-ai-products-start-building-workflows#chatting-with-your-internal-data\" class=\"hash-link\" aria-label=\"Direct link to Chatting with your internal data\" title=\"Direct link to Chatting with your internal data\">​</a></h2>\n<p>If you're building a general-purpose AI model to be used on any user data, and your pitch is: our model is better at retrieval than any other AI lab.</p>\n<p>Then you've already lost.</p>\n<p>The funny thing is, the companies that fall into this trap will say:</p>\n<blockquote>\n<p><em>\"OpenAI isn't a competitor because we are better at understanding the user data\"</em></p>\n</blockquote>\n<br>\n<p>But then, every time a new model drops they will tell investors:</p>\n<blockquote>\n<p><em>\"Our product just got 2x better because of the latest OpenAI release\"</em></p>\n</blockquote>\n<br>\n<p>You see the irony right?</p>\n<p>If you have <em>this</em> thin of a wrapper, then in the words of Sam Altman — OpenAI will steamroll you.</p>\n<p>I.e., while you're telling investors that your product performance improved thanks to the latest model, we both know that the value gap between using OpenAI directly and your product just got smaller.</p>\n<p>You're fighting a fight you can't win.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"but-our-chatting-interface-is-better\">But our chatting interface is better<a href=\"https://didierlopes.com/blog/stop-building-ai-products-start-building-workflows#but-our-chatting-interface-is-better\" class=\"hash-link\" aria-label=\"Direct link to But our chatting interface is better\" title=\"Direct link to But our chatting interface is better\">​</a></h2>\n<p>How is it better?</p>\n<ul>\n<li>Does it create charts and tables?</li>\n<li>Does it create artifacts?</li>\n<li>Does it highlight citations?</li>\n<li>Does it provide reasoning?</li>\n<li>Does it do web search?</li>\n<li>Does it do deep research?</li>\n<li>Does it allow you to upload documents?</li>\n</ul>\n<p>I'm sorry to tell you, but OpenAI already does all these things.</p>\n<p>Even worse - in the financial services, firms are likely already using Microsoft or Google as a cloud vendor.</p>\n<p>And both of these have products where OpenAI and Gemini, respectively, work on top of firm's data.</p>\n<p>So why would a firm even look at your product if this is where you fall?</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"what-about-perplexity\">What about Perplexity?<a href=\"https://didierlopes.com/blog/stop-building-ai-products-start-building-workflows#what-about-perplexity\" class=\"hash-link\" aria-label=\"Direct link to What about Perplexity?\" title=\"Direct link to What about Perplexity?\">​</a></h2>\n<p>Perplexity needs to be studied. For good reasons.</p>\n<p>They fine-tuned an open-weight model and used it for web search.</p>\n<p>Nothing groundbreaking here.</p>\n<p>Except that their execution is seamless.</p>\n<p>They did it much earlier than any of the main AI labs—and every day that passed, Perplexity was gaining market share around AI for querying the internet.</p>\n<p>While they were gaining market share, they never let the momentum die—either through launches, partnerships, competitions...</p>\n<p>And so today, although OpenAI and others have web search, Perplexity is considered the best product for queries that involve the web.</p>\n<p>Ultimately, I think their moat is a combination of being first to market (on search), having a strong brand, and—more importantly—flawless execution by Aravind.</p>\n<p>One of the things I never understood was why they didn't push more on the Enterprise AI angle. After all, they have the best demo there is:</p>\n<blockquote>\n<p><em>\"If we can give you an answer based on a personal blog post written 17 years ago by a professor of history from Portugal, do you really think we can't get your 'extract the company's last twelve months' revenue'?\"</em></p>\n</blockquote>\n<br>\n<p>But they announced crossing $100M ARR, so they're doing pretty well.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"where-does-the-highest-value-lie\">Where does the highest value lie?<a href=\"https://didierlopes.com/blog/stop-building-ai-products-start-building-workflows#where-does-the-highest-value-lie\" class=\"hash-link\" aria-label=\"Direct link to Where does the highest value lie?\" title=\"Direct link to Where does the highest value lie?\">​</a></h2>\n<p>I'm seeing two dimensions here:</p>\n<ol>\n<li>Data</li>\n<li>Workflows</li>\n</ol>\n<br>\n<p>Let's approach each individually.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"1-data\">1. Data<a href=\"https://didierlopes.com/blog/stop-building-ai-products-start-building-workflows#1-data\" class=\"hash-link\" aria-label=\"Direct link to 1. Data\" title=\"Direct link to 1. Data\">​</a></h3>\n<p>When it comes to data, we are talking about:</p>\n<blockquote>\n<p><em>Do you have your own proprietary data that firms would pay for?</em></p>\n</blockquote>\n<br>\n<p>If the answer is yes—then <em>this</em> is your moat.</p>\n<p>Note that this has nothing to do with AI, but with the data itself.</p>\n<p>AI is just the delivery mechanism for that data. Not an API call, not a dashboard with the data, not a notification... a box that expects natural language and returns the data.</p>\n<p>If the answer is no, then you don't have a moat here.</p>\n<p><strong>BUT.</strong></p>\n<p>If you were thinking, <em>\"But my application connects with data from FactSet, S&amp;P, ...\"</em></p>\n<p>Then your moat is not the data itself, but the <strong>workflow</strong>—which takes me to the next moat discussion.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"2-workflows\">2. Workflows<a href=\"https://didierlopes.com/blog/stop-building-ai-products-start-building-workflows#2-workflows\" class=\"hash-link\" aria-label=\"Direct link to 2. Workflows\" title=\"Direct link to 2. Workflows\">​</a></h3>\n<p>Here, the question is: what types of workflows do you allow users to get done on your product?</p>\n<p>The definition of a <em>workflow</em> is: a sequence of steps or tasks that are carried out to complete a specific process or achieve a particular goal.</p>\n<p>There's no mention of AI anywhere in that definition. AI is a tool that can help get a workflow done, but it isn't required.</p>\n<p>What <em>is</em> required is understanding users—and understanding what they want to get done.</p>\n<p>So there's a <em>lot</em> of value in going narrow and nailing the workflow for a specific type of user.</p>\n<p><em>\"But if you go narrow in a vertical, can't you be disrupted more easily?\"</em> — you ask.</p>\n<p>Yes and no.</p>\n<ul>\n<li>\n<p><strong>YES</strong>, if OpenAI ultimately wanted to go after that market, it could. But OpenAI won't care. Not necessarily because the market isn't big, but because they're pursuing one that's even bigger.</p>\n</li>\n<li>\n<p><strong>NO</strong>, because the more vertical and narrow you go, the fewer experts there are, the stronger the word-of-mouth is, and the lower the competition. And once you're in—you have first-mover advantage.</p>\n</li>\n</ul>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"examples\">Examples<a href=\"https://didierlopes.com/blog/stop-building-ai-products-start-building-workflows#examples\" class=\"hash-link\" aria-label=\"Direct link to Examples\" title=\"Direct link to Examples\">​</a></h2>\n<p>Cursor and Windsurf are amazing products because they <em>nail the workflow</em> of developers.</p>\n<p>It's not just about the AI model being used—but <em>when</em> and <em>how</em> it's used.</p>\n<p>It's about being in a full IDE that users are already familiar with, and plugging in the AI at the exact moments a user needs it.</p>\n<p>They understood the pain of developers—and used AI to alleviate that pain.</p>\n<p>The moat is in nailing the workflow and the user experience.</p>\n<p><strong>What about better models being released? How do they impact these products?</strong></p>\n<p>They get better.</p>\n<p>Because the developers behind the product understand how to use these better models to remove <em>even more</em> friction for their users.</p>\n<p>Another thing worth saying here—I don't actually believe in users selecting different models.</p>\n<p>It sounds good in theory, but in practice, it doesn't really work.</p>\n<p>I don't care what model Cursor is using—I care about getting my workflow done.</p>\n<p>As a developer, I have <em>zero</em> loyalty to my tools. I'll use whatever gets the job done faster and more efficiently.</p>\n<p>I mean—how many people actually switch models manually on Cursor? I think not many, and definitely not frequently.</p>\n<p>I, for one, use Claude because it's the best for coding right now. But if I'm asking an implementation question, then I'll click on the \"Claude Thinking\" model.</p>\n<p>Do I <em>want</em> to click on \"Thinking model\"? Not really. But Cursor doesn't yet understand my intent to get all the \"firepower\" I can for this answer—so for now, this will do.</p>\n<p>Even better—do I <em>really</em> care that it's Claude? Nope. If it turns out Gemini 2.5 is the best at coding, I'll happily switch and never look back.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"openbb\">OpenBB<a href=\"https://didierlopes.com/blog/stop-building-ai-products-start-building-workflows#openbb\" class=\"hash-link\" aria-label=\"Direct link to OpenBB\" title=\"Direct link to OpenBB\">​</a></h2>\n<p>Ok, so where do we fit?</p>\n<p>We're very much in the category of <strong>Workflows</strong> - similar to Cursor.</p>\n<p>The difference is: we didn't have a VSCode that we could fork and build on top of.</p>\n<p>The best financial terminals used in the space — Bloomberg, FactSet, CapIQ — are all closed-source.</p>\n<p>So we had to build <strong>OpenBB Workspace</strong> from scratch over three years to match the capability and quality that financial professionals expect.</p>\n<p>And now, we're adding AI where it makes sense.</p>\n<p>Some of these workflows that can be done on OpenBB include:</p>\n<ol>\n<li><strong>Public Equity</strong>: Earnings guidance intelligence; Investor call preparation.</li>\n<li><strong>Wealth Management</strong>: AI-Generated investment notes; Portfolio optimization &amp; risk management.</li>\n<li><strong>Private Equity &amp; Credit</strong>: AI-enhanced due diligence; Credit data room intelligence.</li>\n<li><strong>Crypto</strong>: On-chain &amp; off-chain analysis; Sentiment &amp; community perception tracking.</li>\n<li><strong>Commodities &amp; Macro</strong>: Scenario-based forecasting; Regime shift analysis.</li>\n<li><strong>Client Advisory</strong>: Generate draft investor letters; Client sentiment analysis.</li>\n<li><strong>Logistics &amp; Operations</strong>: Bunkering intelligence; Regulatory compliance &amp; risk monitoring.</li>\n</ol>\n<br>\n<p>And we're adding more fast.</p>\n<p>Now that we have a UI that meets industry standards, we can double down on <strong>workflows that delight customers</strong>.</p>\n<p>And we'll keep expanding how many workflows can be done on OpenBB—ultimately with the goal of making OpenBB the <strong>central interface</strong> used within a firm, built on top of their own data.</p>\n<p>Here's an example of an application built on OpenBB in just a couple of days by one of our engineers, for a workshop we're putting together with risk managers:</p>\n<p align=\"center\"><img width=\"900\" src=\"https://didierlopes.com/blog/2025-04-03-stop-building-ai-products-start-building-workflows_1.webp\"></p>\n<p>This highlights not only what we've built, but also how quickly we can delight customers on top of our product.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/stop-building-ai-products-start-building-workflows",
            "title": "Stop building AI products, start building workflows",
            "summary": "The secret to building defensible AI companies isn't better AI - it's better workflows. An insider's perspective on why some AI companies thrive while others will become obsolete with each new model release.",
            "date_modified": "2025-04-03T00:00:00.000Z",
            "tags": [
                "ai",
                "product-strategy",
                "business",
                "startup",
                "moat",
                "workflows",
                "openbb",
                "fintech",
                "vertical-ai"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/one-data-vendor-to-rule-them-all-really",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-03-25-one-data-vendor-to-rule-them-all-really.webp\"></p>\n<p>Exploring why relying on a single data vendor for financial research is unrealistic in today's complex market landscape, and how AI-driven platforms like OpenBB are transforming how professionals interact with diverse data sources to find alpha and gain competitive advantage.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"context\">Context<a href=\"https://didierlopes.com/blog/one-data-vendor-to-rule-them-all-really#context\" class=\"hash-link\" aria-label=\"Direct link to Context\" title=\"Direct link to Context\">​</a></h2>\n<p>For those who don't know, the main reason I started OpenBB was because my investment research process started taking too much time.</p>\n<p>As I was adding more data I wanted to analyze in my workflow (e.g. insider trading, macro, options), I spent more time doing \"research\".</p>\n<p>I say \"research\" because in reality, I was spending most of my time on manual tasks.</p>\n<p>Those tasks were a combination of:</p>\n<ul>\n<li>Going into a certain browser tab</li>\n<li>Logging in into my account in the website</li>\n<li>Selecting the ticker of interest</li>\n<li>Extracting the data (e.g. download or taking a screenshot to the chart)</li>\n<li>Potentially processing that data in some capacity (e.g. sentiment for text from Stocktwits or X)</li>\n<li>Putting that data into a document</li>\n</ul>\n<br>\n<p>As a full-time sensor fusion engineer, I didn't have that many hours a day to spend doing research - so this started to occupy most of my weekends.</p>\n<p>As an engineer would, I decided to automate my workflow and that's when I started working on OpenBB as a data aggregator that I could use to become more efficient.</p>\n<p>When I open sourced OpenBB, we saw hundreds of contributors adding data sources they were interested in exploring. Here are a few we incorporated: FMP, Intrinio, Polygon, Tiingo, Yahoo Finance, CoinGecko, CoinPaprika, Coinbase, Binance, CryptoCompare, Alpha Vantage, OANDA, ExchangeRate-API, Federal Reserve Economic Data (FRED), World Bank, OECD, U.S. Department of the Treasury, FINRA, Quandl, SentimentInvestor, Reddit, Stocktwits, Twitter, Google Trends, News API, Finnhub, Benzinga, Seeking Alpha, Wall Street Journal, MarketWatch, Databento, CBOE, SEC EDGAR, Biztoc, StockGrid, Finviz, and more.</p>\n<p>Yup, there was a lot.</p>\n<p>My screen looked like this:</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-03-25-one-data-vendor-to-rule-them-all-really_1.webp\"></p>\n<p>It turns out that professionals had the same pain points that I did. This widespread adoption revealed a fundamental truth about the financial data landscape that continues to shape our vision today.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"a-single-data-vendor\">A single data vendor<a href=\"https://didierlopes.com/blog/one-data-vendor-to-rule-them-all-really#a-single-data-vendor\" class=\"hash-link\" aria-label=\"Direct link to A single data vendor\" title=\"Direct link to A single data vendor\">​</a></h2>\n<p>How likely is it that ALL the data you will want exists under a single data vendor?</p>\n<p>It's just not realistic, even for a company like Bloomberg.</p>\n<p>I mean, think about the following categories and the amount of companies that have a strong hold in the market:</p>\n<ul>\n<li>Equity Market Data &amp; Analytics: Bloomberg, FactSet, LSEG</li>\n<li>Credit Ratings: S&amp;P Global Ratings, Moody's</li>\n<li>Risk Analytics: MSCI</li>\n<li>Portfolio Management: BlackRock (Aladdin platform)</li>\n<li>Fixed Income Data: Bloomberg</li>\n<li>Derivatives &amp; Exchange Trading Infrastructure: CME Group, ICE</li>\n<li>Commodities Trading Data: CME Group, London Metal Exchange (LME)</li>\n<li>Crypto: Dune, Messari, Nansen</li>\n</ul>\n<p>This means that professionals have two paths:</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"need-multiple-products\">Need multiple products<a href=\"https://didierlopes.com/blog/one-data-vendor-to-rule-them-all-really#need-multiple-products\" class=\"hash-link\" aria-label=\"Direct link to Need multiple products\" title=\"Direct link to Need multiple products\">​</a></h3>\n<p>If they cannot do all of their work from a single platform, that means that almost by definition their process is flawed.</p>\n<p>They will have issues combining data, finding edge between different datasets or even learning different tools to get the job done.</p>\n<p>This gets particularly worse when professionals want to incorporate their own internal data.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"can-do-everything-in-one-product\">Can do everything in one product<a href=\"https://didierlopes.com/blog/one-data-vendor-to-rule-them-all-really#can-do-everything-in-one-product\" class=\"hash-link\" aria-label=\"Direct link to Can do everything in one product\" title=\"Direct link to Can do everything in one product\">​</a></h3>\n<p>If they can do all of their work within one interface, then that's perfect.</p>\n<p>The main question they need to ask is: \"Can I trust this company to adapt to AI so I can be as efficient as my peers?\".</p>\n<p>If the answer is yes, then they shouldn't look at other products.</p>\n<p>If not, then they should prepare to adapt.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"the-role-of-ai\">The role of AI<a href=\"https://didierlopes.com/blog/one-data-vendor-to-rule-them-all-really#the-role-of-ai\" class=\"hash-link\" aria-label=\"Direct link to The role of AI\" title=\"Direct link to The role of AI\">​</a></h2>\n<p>As AI gets better, it will be harder for humans to find Alpha.</p>\n<p>This isn't just speculation. We're already seeing evidence of this transformation.</p>\n<p>I believe that AI will be able to find Alpha at the intersection of different datasets and their relationships, or even utilizing proprietary data (which third party products do not offer).</p>\n<p>Regardless, for that you need an AI-first enterprise UI.</p>\n<p>This is what we are building at OpenBB – not just another data aggregator, but an intelligent interface that:</p>\n<ul>\n<li>Unifies fragmented data sources into a coherent ecosystem</li>\n<li>Applies AI to identify patterns and relationships that humans might miss</li>\n<li>Adapts to your unique workflow and proprietary data</li>\n<li>Reduces the friction between question and insight</li>\n</ul>\n<p align=\"center\"><img width=\"900\" src=\"https://didierlopes.com/blog/2025-03-25-one-data-vendor-to-rule-them-all-really_2.webp\"></p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"the-role-of-data\">The role of data<a href=\"https://didierlopes.com/blog/one-data-vendor-to-rule-them-all-really#the-role-of-data\" class=\"hash-link\" aria-label=\"Direct link to The role of data\" title=\"Direct link to The role of data\">​</a></h2>\n<p>Due to the role of AI, and how data-hungry it is - it's becoming clear that investment firms will start acquiring more and more data internally.</p>\n<p>The issue with this is that data by itself doesn't do much.</p>\n<p>You need an interface to analyze that data or for AI to do so.</p>\n<p>OpenBB Workspace is precisely this – the critical missing piece that transforms raw data into actionable intelligence.</p>\n<p>Where traditional platforms simply aggregate information, our solution applies intelligence to that information, creating a multiplier effect on your data investments.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"the-power-shift-from-data-to-interface\">The power shift: From data to interface<a href=\"https://didierlopes.com/blog/one-data-vendor-to-rule-them-all-really#the-power-shift-from-data-to-interface\" class=\"hash-link\" aria-label=\"Direct link to The power shift: From data to interface\" title=\"Direct link to The power shift: From data to interface\">​</a></h2>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-03-25-one-data-vendor-to-rule-them-all-really_3.webp\"></p>\n<p>Historically, the power in financial markets has been centered around data access. The interface was merely a distribution channel - a means to an end.</p>\n<p>But this model has been limiting for some time now.</p>\n<p>Think about it: All humans are different in how we process information, yet somehow we're all expected to use the same software interfaces?</p>\n<p>Make it make sense.</p>\n<p>The reality is that each professional has unique cognitive patterns, analytical strengths, and decision-making processes. A one-size-fits-all approach to financial interfaces is fundamentally at odds with how humans actually work.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"owning-your-workflow\">Owning your workflow<a href=\"https://didierlopes.com/blog/one-data-vendor-to-rule-them-all-really#owning-your-workflow\" class=\"hash-link\" aria-label=\"Direct link to Owning your workflow\" title=\"Direct link to Owning your workflow\">​</a></h2>\n<p>As firms consume more data from diverse sources, they should also own their workflow and interface.</p>\n<p>Why?</p>\n<ol>\n<li><strong>Competitive advantage</strong>: Your unique process is what differentiates you in the market</li>\n<li><strong>Adaptability</strong>: Markets evolve rapidly - your tools should evolve with them</li>\n<li><strong>Integration</strong>: Proprietary data becomes truly valuable when seamlessly incorporated into your workflow</li>\n<li><strong>Personalization</strong>: Different team members need different views of the same data</li>\n</ol>\n<br>\n<p>This is why OpenBB Workspace is designed to be adaptable to your specific needs - not forcing you into a rigid framework, but empowering you to create the exact workflow that matches how your team thinks and operates.</p>\n<p>Plus, you can <strong>fully own</strong> your workflow, data and everything in between.</p>\n<p align=\"center\"><img width=\"900\" src=\"https://didierlopes.com/blog/2025-03-25-one-data-vendor-to-rule-them-all-really_4.webp\"></p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"looking-ahead\">Looking ahead<a href=\"https://didierlopes.com/blog/one-data-vendor-to-rule-them-all-really#looking-ahead\" class=\"hash-link\" aria-label=\"Direct link to Looking ahead\" title=\"Direct link to Looking ahead\">​</a></h2>\n<p>The financial data landscape will only grow more complex. The winners will be those who can seamlessly integrate diverse data sources, apply AI effectively, and maintain adaptability as technology evolves.</p>\n<p>OpenBB Workspace is designed with this future in mind – not just solving today's problems but positioning our clients to thrive in the AI-driven financial world that's rapidly emerging.</p>\n<p>If you're ready to transform how your team interacts with financial data, we'd love to show you what's possible with OpenBB Workspace.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/one-data-vendor-to-rule-them-all-really",
            "title": "One data vendor to rule them all. Really?",
            "summary": "Exploring why relying on a single data vendor for financial research is unrealistic in today's complex market landscape, and how AI-driven platforms like OpenBB are transforming how professionals interact with diverse data sources to find alpha and gain competitive advantage.",
            "date_modified": "2025-03-25T00:00:00.000Z",
            "tags": [
                "openbb",
                "financial-data",
                "data-aggregation",
                "investment-research",
                "workflow-automation",
                "data-vendors",
                "alpha-generation"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/openbb-enables-streamlined-client-advisory-ai-workflow",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-03-23-openbb-enables-streamlined-client-advisory-ai-workflow.webp\"></p>\n<p>In this blog post, I'll show you how an AI agent can transform your funds performance, macro data, news around your holding companies, and more into a draft investor letter that has the same writing style as your team.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>Gathering performance data, analyzing market shifts, and crafting detailed investor communications is a process that demands precision, consistency, and a personal touch.</p>\n<p>But what if your analysts could have an AI writing partner that thinks and communicates just like your team and could prepare those drafts in a few minutes?</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-03-23-openbb-enables-streamlined-client-advisory-ai-workflow_1.webp\"></p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"how-does-it-work\">How does it work?<a href=\"https://didierlopes.com/blog/openbb-enables-streamlined-client-advisory-ai-workflow#how-does-it-work\" class=\"hash-link\" aria-label=\"Direct link to How does it work?\" title=\"Direct link to How does it work?\">​</a></h2>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"step-1-custom-pdf-parsing-of-factsheets\">Step 1: Custom PDF parsing of factsheets<a href=\"https://didierlopes.com/blog/openbb-enables-streamlined-client-advisory-ai-workflow#step-1-custom-pdf-parsing-of-factsheets\" class=\"hash-link\" aria-label=\"Direct link to Step 1: Custom PDF parsing of factsheets\" title=\"Direct link to Step 1: Custom PDF parsing of factsheets\">​</a></h3>\n<p>First, the agent tackles the challenge of extracting structured data from your quarterly factsheets.</p>\n<p>Using a combination of OCR and state-of-the-art LLM models with structured output, it can capture all the relevant information from the document with a high degree of accuracy.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-03-23-openbb-enables-streamlined-client-advisory-ai-workflow_2.webp\"></p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"step-2-learning-your-communication-style\">Step 2: Learning your communication style<a href=\"https://didierlopes.com/blog/openbb-enables-streamlined-client-advisory-ai-workflow#step-2-learning-your-communication-style\" class=\"hash-link\" aria-label=\"Direct link to Step 2: Learning your communication style\" title=\"Direct link to Step 2: Learning your communication style\">​</a></h3>\n<p>Processing your investor letters is significantly easier, as they usually consist of text, which can be easily parsed to markdown format (ideal for LLMs), and simpler tables, easily identified by the latest models.</p>\n<p>So in this step, the important aspect is identifying what makes your ~10-page investor letter unique. To be able to do that, the agent needs several quarter investor letters so it can understand the patterns and similarities between them and answer questions like:</p>\n<ul>\n<li>How does the analyst write the intro?</li>\n<li>How do they wrap up the letter? Does it change based on the overall flow?</li>\n<li>What are the sections of the document (e.g., performance review, outlook)?</li>\n<li>What is the analyst's tone of voice in general? Does it change based on the performance review?</li>\n<li>How much detail does it go into regarding the major holdings?</li>\n<li>Do they talk about positions that were exited and why? What about new ones?\n...</li>\n</ul>\n<p>Ultimately, the model needs to understand what makes your investor letter unique.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-03-23-openbb-enables-streamlined-client-advisory-ai-workflow_3.webp\"></p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"step-3-pattern-recognition-between-factsheet-and-investor-letter\">Step 3: Pattern recognition between factsheet and investor letter<a href=\"https://didierlopes.com/blog/openbb-enables-streamlined-client-advisory-ai-workflow#step-3-pattern-recognition-between-factsheet-and-investor-letter\" class=\"hash-link\" aria-label=\"Direct link to Step 3: Pattern recognition between factsheet and investor letter\" title=\"Direct link to Step 3: Pattern recognition between factsheet and investor letter\">​</a></h3>\n<p>At this point, it already knows what makes your investor letter unique. However, it still does not know what makes the analyst write certain comments vs others. Where do these come from?</p>\n<p>For that, we are picking the concept of \"supervised learning\" from machine learning, where a model is trained based on the input and output to understand the trends between the two.</p>\n<p>In this case:</p>\n<ul>\n<li>The model is the LLM of your choice (e.g., local LLM so data doesn't leave your machine)</li>\n<li>The input is the factsheet data</li>\n<li>The output is the investor letter</li>\n</ul>\n<p>And we use a prompt along the lines of:</p>\n<blockquote>\n<p>Can you extract the structure/pattern between the factsheet data and what is written in this investor letter? Your goal is to output instructions that can be used as a prompt for a model to predict what the analyst would write based on that factsheet data.</p>\n</blockquote>\n<br>\n<p>We are ultimately looking for a detailed \"recipe\" that connects your factsheet data to what your analyst would write.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-03-23-openbb-enables-streamlined-client-advisory-ai-workflow_4.webp\"></p>\n<p>The AI learns exactly how your team moves from raw numbers to meaningful insights, maintaining your analytical frameworks and professional voice.</p>\n<p>It allows you to understand which factsheet data tables impact which section of the investor letter and how.</p>\n<p><strong>Tips &amp; tricks:</strong></p>\n<ol>\n<li>\n<p>Feed the model with multiple different \"Factsheet → Investor letter\" examples so it's easier for it to capture edge cases. Example: The last quarter of the year might have a different section to wrap up the year</p>\n</li>\n<li>\n<p>Do not use examples that had a different writing style than what you're trying to achieve as that can impact the results. Example: an example from 7 years ago might no longer be relevant due to overall style changes</p>\n</li>\n<li>\n<p>Go more granular. Instead of using the entire document as an example, go after a subset of the data. Example: If the performance section of the Investor letter only relies on 4 of the 14 tables, focus on those only to extract a pattern</p>\n</li>\n<li>\n<p>Get the main analyst responsible for the investment letters involved in this process. Having a subject matter expert is essential here and will be a deal breaker.</p>\n</li>\n</ol>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"step-4-preparing-your-prompt\">Step 4: Preparing your prompt<a href=\"https://didierlopes.com/blog/openbb-enables-streamlined-client-advisory-ai-workflow#step-4-preparing-your-prompt\" class=\"hash-link\" aria-label=\"Direct link to Step 4: Preparing your prompt\" title=\"Direct link to Step 4: Preparing your prompt\">​</a></h3>\n<p>The agent has now found:</p>\n<ul>\n<li>Your communication style, which will be used as a system prompt</li>\n<li>The recipe to write the investor letter based on factsheet data, which will be used as the user prompt</li>\n<li>Examples of factsheet data and their resulting investor letters, which will be used for few-shot prompt</li>\n<li>A model that we have decided to use (whether OpenAI, open weights model like Llama, or other)</li>\n</ul>\n<p>However, we still need to provide the model with:</p>\n<ul>\n<li>Latest factsheet data</li>\n<li>Any additional context to be included in the letter (e.g., tickers of interest for this quarter, macro, ..)</li>\n</ul>\n<p>That's where the OpenBB workspace is crucial.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"step-5-connect-this-custom-agent-to-the-openbb-workspace\">Step 5: Connect this custom agent to the OpenBB workspace<a href=\"https://didierlopes.com/blog/openbb-enables-streamlined-client-advisory-ai-workflow#step-5-connect-this-custom-agent-to-the-openbb-workspace\" class=\"hash-link\" aria-label=\"Direct link to Step 5: Connect this custom agent to the OpenBB workspace\" title=\"Direct link to Step 5: Connect this custom agent to the OpenBB workspace\">​</a></h3>\n<p>It doesn't matter how good this pipeline is if your team does not have a good interface to interact with it easily—feed it the data it requires, review its output, iterate, etc.</p>\n<p>By connecting this custom agent to the OpenBB workspace, your firm can access it directly from there and combine it with the other features OpenBB offers.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-03-23-openbb-enables-streamlined-client-advisory-ai-workflow_5.webp\"></p>\n<p>Those features include:</p>\n<ul>\n<li>Being able to drag and drop to the workspace the latest factsheet data and any additional context that the model will require</li>\n<li>Interact with the model directly on OpenBB's interface</li>\n<li>Review the generated draft directly and ask for quick edits or adjustments</li>\n<li>Convert that draft into a widget on the workspace</li>\n<li>Share this initial draft version with your team for feedback</li>\n</ul>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-03-23-openbb-enables-streamlined-client-advisory-ai-workflow_6.webp\"></p>\n<p>Our unique solution consists of an AI-ready interface where firms can seamlessly integrate their own data and AI agents. This means that these agents are accessible right where your analysts perform their analysis and research, eliminating the need to switch between platforms or learn new tools. This approach allows portfolio managers and analysts to leverage AI to complement their existing processes, rather than relying on generic solutions.</p>\n<p>OpenBB also stands out because it's built on an open-source foundation, unlike anything else in the market, translating into unparalleled transparency, flexibility, and the ability to adapt to your unique needs.</p>\n<p>Additionally, our flexible on-prem deployment option means that firms can run open-weight AI models locally and that data never leaves their environment, ensuring privacy and compliance.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"summing-up\">Summing up<a href=\"https://didierlopes.com/blog/openbb-enables-streamlined-client-advisory-ai-workflow#summing-up\" class=\"hash-link\" aria-label=\"Direct link to Summing up\" title=\"Direct link to Summing up\">​</a></h2>\n<p>While the results can make it look simple, in reality, this is how the pipeline works under the hood:</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-03-23-openbb-enables-streamlined-client-advisory-ai-workflow_7.webp\"></p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"real-life-results-on-our-clients-operations\">Real-life results on our clients' operations<a href=\"https://didierlopes.com/blog/openbb-enables-streamlined-client-advisory-ai-workflow#real-life-results-on-our-clients-operations\" class=\"hash-link\" aria-label=\"Direct link to Real-life results on our clients' operations\" title=\"Direct link to Real-life results on our clients' operations\">​</a></h3>\n<p>The impact of this workflow on our clients' operations has been transformative. Analysts now have first drafts ready within minutes of receiving factsheet data, giving them more time to focus on analysis and personalization. The consistency in communications has improved, while the accuracy of data and insights remains impeccable.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"increase-your-teams-throughput-and-efficiency-with-ai\">Increase your team's throughput and efficiency with AI<a href=\"https://didierlopes.com/blog/openbb-enables-streamlined-client-advisory-ai-workflow#increase-your-teams-throughput-and-efficiency-with-ai\" class=\"hash-link\" aria-label=\"Direct link to Increase your team's throughput and efficiency with AI\" title=\"Direct link to Increase your team's throughput and efficiency with AI\">​</a></h3>\n<p>Imagine you have an AI partner that thinks like your team, writes like your team, and helps maintain the high standards your investors expect. A partner that's always available, consistently accurate, and infinitely scalable.</p>\n<p>That's something OpenBB can help you achieve.</p>\n<p>Whether you manage multiple funds, communicate in different languages, or simply want to give your analysts more time for high-value work, we're excited to explore how we can transform your investment communications process.</p>\n<p>Interested in seeing how this could work for your firm?</p>\n<p>Let's discuss how we can customize this solution for your organization's unique needs and communication style. Contact me at <a href=\"mailto:didier.lopes@openbb.finance\" target=\"_blank\" rel=\"noopener noreferrer\">didier.lopes@openbb.finance</a>.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/openbb-enables-streamlined-client-advisory-ai-workflow",
            "title": "OpenBB enables streamlined Client Advisory AI workflow",
            "summary": "In this blog post, I'll show you how an AI agent can transform your funds performance, macro data, news around your holding companies, and more into a draft investor letter that has the same writing style as your team.",
            "date_modified": "2025-03-23T00:00:00.000Z",
            "tags": [
                "openbb",
                "ai",
                "llm",
                "fintech",
                "automation",
                "workflows",
                "client-advisory",
                "investment-management",
                "reporting"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/my-first-half-marathon",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-03-18-my-first-half-marathon.webp\"></p>\n<p>A personal journey through my first NYC Half Marathon, from fundraising $1,615 for cancer research to crossing the finish line in 1h45min, complete with training insights and my race day experience.</p>\n<!-- -->\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"background\">Background<a href=\"https://didierlopes.com/blog/my-first-half-marathon#background\" class=\"hash-link\" aria-label=\"Direct link to Background\" title=\"Direct link to Background\">​</a></h2>\n<p>I'm currently 29 years old.</p>\n<p>That means that as other hundred of thousands of runners, I'm having a mid-life crisis... just kidding.</p>\n<p>Last year, I signed up to participate in a boxing match for Haymakers for Hope - where I would have to raise $10k for Cancer research.</p>\n<p>I didn't get selected in the end.</p>\n<p>However, raising money for charity (something I had never done before) was something that I've always wanted to do. Particularly when it affected me so much at a young age (more on that <a href=\"http://didierlopes.com/blog/inspired-by-bia-how-her-fight-against-cancer-changed-my-life/\" target=\"_blank\">here</a>).</p>\n<p>So when I received an email about the United NYC Half marathon, organized by Haymakers for Hope. I had to sign up.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"fundraising\">Fundraising<a href=\"https://didierlopes.com/blog/my-first-half-marathon#fundraising\" class=\"hash-link\" aria-label=\"Direct link to Fundraising\" title=\"Direct link to Fundraising\">​</a></h2>\n<p>The New York City Half Marathon is incredibly popular, with nearly 30,000 people participating this year. Unlike most races, you can't simply sign up - you actually need to apply through an organization that has allocated \"bibs\" for the race.</p>\n<p>If you're accepted, you commit to raising money for the chosen cause. I love this approach because it means everyone running on race day has raised funds for organizations they're passionate about, giving the event deeper meaning and purpose.</p>\n<p>In my case, I commit to raise at least $1500. In total I was able to raise $1615.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-03-18-my-first-half-marathon_1.webp\"></p>\n<p>Although I've previously raised $8.9M for OpenBB, as mentioned in <a href=\"https://venturebeat.com/data-infrastructure/openbb-wants-to-be-an-open-source-challenger-to-bloomberg-terminal/\" target=\"_blank\">this article</a>. Raising wasn't straightforward.</p>\n<p>Here are a few things that I did in order to raise this amount:</p>\n<ul>\n<li>I shared the <a href=\"http://didierlopes.com/blog/inspired-by-bia-how-her-fight-against-cancer-changed-my-life/\" target=\"_blank\">story of Bia</a> and why this cause is important to me. First on socials and then on my newsletter.</li>\n<li>I asked my closest friends and family to support me in this cause.</li>\n<li>For the people that couldn't support, I asked to repost my fundraising efforts for higher visibility.</li>\n<li>Added that CTA on the top of my website, where I share blogs weekly.</li>\n</ul>\n<p>Other things that I was thinking of doing, but ended up not requiring to do so:</p>\n<ul>\n<li>Asking if any company would like to contribute to the fundraising and I would run with their merch</li>\n<li>Doing a stream on building something from scratch where I have on the banner that I'm raising money for Cancer</li>\n<li>Selling items that I don't use as much anymore</li>\n</ul>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"preparation-and-paperwork\">Preparation and paperwork<a href=\"https://didierlopes.com/blog/my-first-half-marathon#preparation-and-paperwork\" class=\"hash-link\" aria-label=\"Direct link to Preparation and paperwork\" title=\"Direct link to Preparation and paperwork\">​</a></h2>\n<p>The administrative side of race preparation was straightforward but required attention to detail:</p>\n<p>First, I had to sign up with New York Road Runners (<a href=\"https://www.nyrr.org/\" target=\"_blank\">NYRR</a>).</p>\n<div class=\"theme-admonition theme-admonition-note admonition_xJq3 alert alert--secondary\"><div class=\"admonitionHeading_Gvgb\"><span class=\"admonitionIcon_Rf37\"><svg viewBox=\"0 0 14 16\"><path fill-rule=\"evenodd\" d=\"M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z\"></path></svg></span>note</div><div class=\"admonitionContent_BuS1\"><p>Important tip: be realistic about your estimated completion time.</p><br><p>This determines your starting wave. I conservatively estimated 2 hours since it was my first half marathon, but I should have put 1:45 instead. A faster wave would have meant less congestion at the start, and going with runners that are aiming to do the same time as I am.</p></div></div>\n<p>This is what the wave scheduled looked like.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-03-18-my-first-half-marathon_2.webp\"></p>\n<p>After paying the race fee, I scheduled my bib pickup.</p>\n<p>The pickup location was actually great! There was a ton of race merchandise, giveaways, photoshoots and more going on.</p>\n<div class=\"theme-admonition theme-admonition-note admonition_xJq3 alert alert--secondary\"><div class=\"admonitionHeading_Gvgb\"><span class=\"admonitionIcon_Rf37\"><svg viewBox=\"0 0 14 16\"><path fill-rule=\"evenodd\" d=\"M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z\"></path></svg></span>note</div><div class=\"admonitionContent_BuS1\"><p>Check that you get the running bib, your number that contains the chip tracker and the clips to set them on. For instance, mine had a missing clip to attach it to the shirt.</p></div></div>\n<p>The location also displayed a wall with all runner's names, my mom actually found my name on the wall!</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-03-18-my-first-half-marathon_3.webp\"></p>\n<p>I also took an event guide, which had pretty much all the information I needed for the day of the race.</p>\n<div style=\"display:flex;justify-content:center;gap:20px\"><img width=\"45%\" src=\"https://didierlopes.com/blog/2025-03-18-my-first-half-marathon_4.webp\"><img width=\"45%\" src=\"https://didierlopes.com/blog/2025-03-18-my-first-half-marathon_5.webp\"></div>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"training\">Training<a href=\"https://didierlopes.com/blog/my-first-half-marathon#training\" class=\"hash-link\" aria-label=\"Direct link to Training\" title=\"Direct link to Training\">​</a></h2>\n<p>My training wasn't as structured as it could have been, but my regular boxing sessions (2-3 times weekly) provided a great foundation.</p>\n<p>To ensure I could complete the distance, I ran a practice half marathon one month before the race near my boxing Gym Gleason's, finishing in 2 hours. This gave me confidence and a benchmark to improve upon.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-03-18-my-first-half-marathon_6.webp\"></p>\n<div style=\"display:flex;justify-content:center;gap:20px\"><img width=\"45%\" src=\"https://didierlopes.com/blog/2025-03-18-my-first-half-marathon_7.PNG\"><img width=\"45%\" src=\"https://didierlopes.com/blog/2025-03-18-my-first-half-marathon_8.PNG\"></div>\n<br>\n<p>A week before the event, I completed a 12-mile run with elevation in Central Park to prepare for any challenging terrain. This made me understand how elevation actually plays a role, since in that previous training session the terrain was very much flat!</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-03-18-my-first-half-marathon_9.webp\"></p>\n<div style=\"display:flex;justify-content:center;gap:20px\"><img width=\"45%\" src=\"https://didierlopes.com/blog/2025-03-18-my-first-half-marathon_10.webp\"><img width=\"45%\" src=\"https://didierlopes.com/blog/2025-03-18-my-first-half-marathon_11.webp\"></div>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"race-day\">Race day<a href=\"https://didierlopes.com/blog/my-first-half-marathon#race-day\" class=\"hash-link\" aria-label=\"Direct link to Race day\" title=\"Direct link to Race day\">​</a></h2>\n<p>For the race day I woke up a couple hours before the event.</p>\n<p>For breakfast, I had three eggs and a banana to provide energy for the run.</p>\n<p>I wore the bib given by the organization with my number plate, non-grip socks, running shoes, shorts with pockets for my airpods box and the Haymakers for Hope hat. This was a good shout as I saw someone from our team on the starting line and they recognized me because of that.</p>\n<p>For garments I brought my AirPods to listen to a Spotify playlist that I had prepared the day before with fast paced music to give a boost. Example of songs in that playlist include:</p>\n<ul>\n<li>\n<a href=\"https://www.youtube.com/watch?v=cdgbI17JbII\" target=\"_blank\" rel=\"noopener noreferrer\">Camo &amp; Krooked - Climax</a>\n</li>\n<li>\n<a href=\"https://www.youtube.com/watch?v=xvtNS6hbVy4\" target=\"_blank\" rel=\"noopener noreferrer\">Deadmau5 feat Chris James - The Veldt</a>\n</li>\n<li>\n<a href=\"https://www.youtube.com/watch?v=Lo0ELoepTCM\" target=\"_blank\" rel=\"noopener noreferrer\">Monolink - Return to Oz (ARTBAT Remix)</a>\n</li>\n</ul>\n<p>Shoutout to <a href=\"https://www.linkedin.com/in/ulyanaermolova/\" target=\"_blank\" rel=\"noopener noreferrer\">Ulyana</a> who shared some of the songs she listens while running!</p>\n<p>I also brought an old sweater to stay warm before the race, which I later donated through the race's clothing drive for charity. I loved this concept.</p>\n<div class=\"theme-admonition theme-admonition-note admonition_xJq3 alert alert--secondary\"><div class=\"admonitionHeading_Gvgb\"><span class=\"admonitionIcon_Rf37\"><svg viewBox=\"0 0 14 16\"><path fill-rule=\"evenodd\" d=\"M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z\"></path></svg></span>note</div><div class=\"admonitionContent_BuS1\"><p>You can actually take more things with you and then check-in that bag before the race. The organization will take that bag to the finish line which you can then pick up by using your bib number or name.</p></div></div>\n<p>With all this preparation, I forgot something that was critical - and I still cannot believe that I did. I forgot my Apple Watch!! 🤦🏽‍♂️</p>\n<p>This resulted in me running with the phone in my hand throughout the race, looking like a schmuck.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-03-18-my-first-half-marathon_12.webp\"></p>\n<p>Note: LLMs are getting so good, that Gemini 2.0 Flash (Image Generation) is now able to remove watermarks of pictures. See <a href=\"https://x.com/didier_lopes/status/1902067982123319637\" target=\"_blank\" rel=\"noopener noreferrer\">this tweet</a> for reference.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"during-the-race\">During the race<a href=\"https://didierlopes.com/blog/my-first-half-marathon#during-the-race\" class=\"hash-link\" aria-label=\"Direct link to During the race\" title=\"Direct link to During the race\">​</a></h3>\n<p>Just before starting, I consumed one of my energy gels for an initial boost.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-03-18-my-first-half-marathon_13.webp\"></p>\n<p>The race experience was awesome in itself. Your timing chip activates when you cross the start line, so your official time is accurate regardless of where you stand in your wave.</p>\n<p>However, starting in a slower wave meant navigating through crowds of runners, which proved challenging at times.</p>\n<p>There were several water and Gatorade stations throughout the course, eliminating the need to carry your own water bottle.</p>\n<p>You will actually receive map course information before the race so you can prepare for where these stations are.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-03-18-my-first-half-marathon_14.webp\"></p>\n<p>The elevation chart on this map is actually very important. This allows you to be strategic when you think about when to conserve your energy or speed up.</p>\n<p>I saw many runners that started walking when they were on a uphill. I think that being able to push through in these sections is critical, since if you break your rhythm then it becomes harder to keep going.</p>\n<p>Running across the Brooklyn Bridge (a first ever for any race!) and through Times Square were big highlights for me.</p>\n<div style=\"display:flex;justify-content:center;gap:10px;flex-wrap:wrap\"><img width=\"32%\" src=\"https://didierlopes.com/blog/2025-03-18-my-first-half-marathon_15.webp\"><img width=\"32%\" src=\"https://didierlopes.com/blog/2025-03-18-my-first-half-marathon_16.webp\"><img width=\"32%\" src=\"https://didierlopes.com/blog/2025-03-18-my-first-half-marathon_17.webp\"></div>\n<br>\n<p>The energy from spectators was also incredible, with creative and humorous signs everywhere.</p>\n<p>Some of my favorites included:</p>\n<ul>\n<li>\"Pain is temporary, Strava is 4eva\"</li>\n<li>\"Your outie is running a half marathon\"</li>\n<li>\"If you slow down I'll drop this\" held by a naked spectator with a strategically placed sign</li>\n<li>\"When you need to actually run the race you signed up for\" with the face of someone screaming</li>\n<li>\"From 1 to 10, you are a 13\"</li>\n<li>\"Run now, beer later\"</li>\n<li>\"You are only running this race because you are half crazy\"</li>\n</ul>\n<p>Around mile 9, I used another of my energy gel to keep going. I used my one instead of the ones provided by the organization as my body knows that gel, and you don't want any surprises on the day.</p>\n<p>Without my watch, I paced myself by mental calculations from my start time. I saved energy for a final push in the last mile to hit my target of 1h:45m.</p>\n<p>Having my parents and wife near the finish line providing support was amazing.</p>\n<p>This is a picture taken by them, with less than 400m left:</p>\n<p align=\"center\"><img width=\"900\" src=\"https://didierlopes.com/blog/2025-03-18-my-first-half-marathon_18.webp\"></p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"after-the-race\">After the race<a href=\"https://didierlopes.com/blog/my-first-half-marathon#after-the-race\" class=\"hash-link\" aria-label=\"Direct link to After the race\" title=\"Direct link to After the race\">​</a></h2>\n<p>As soon as I crossed the finish line, volunteers handed out care packages containing water, Gatorade, a cereal bar, pretzels, and an apple.</p>\n<p>As you walk a few dozen meters, they also hand you your medal and blankets to warm you up. Then there's also locations where people can take pictures.</p>\n<p>Here's the picture I took with my family after leaving the half marathon area.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-03-18-my-first-half-marathon_19.webp\"></p>\n<p>The entire experience exceeded my expectations.</p>\n<p>While running isn't my favorite activity, completing a half marathon with my parents on the finish line was awesome.</p>\n<p>Finally, at home, I sent an e-mail to everyone who donated thanking them for the donation, letting them know how much was raised, and how the event went.</p>\n<p align=\"center\"><img width=\"900\" src=\"https://didierlopes.com/blog/2025-03-18-my-first-half-marathon_20.webp\"></p>\n<p>This is something I borrowed from my friend <a href=\"https://www.linkedin.com/in/nicolasbcarreras/\" target=\"_blank\" rel=\"noopener noreferrer\">Nick</a> when I donated to his team relay race.</p>\n<p>Looking forward to doing a full marathon next!</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"stats\">Stats<a href=\"https://didierlopes.com/blog/my-first-half-marathon#stats\" class=\"hash-link\" aria-label=\"Direct link to Stats\" title=\"Direct link to Stats\">​</a></h2>\n<p>Some stats below for the curious,</p>\n<div style=\"display:flex;justify-content:center;gap:10px;flex-wrap:wrap\"><img width=\"49%\" src=\"https://didierlopes.com/blog/2025-03-18-my-first-half-marathon_21.webp\"><img width=\"49%\" src=\"https://didierlopes.com/blog/2025-03-18-my-first-half-marathon_22.webp\"></div><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/my-first-half-marathon",
            "title": "Doing my first Half Marathon",
            "summary": "A personal journey through my first NYC Half Marathon, from fundraising $1,615 for cancer research to crossing the finish line in 1h45min, complete with training insights and my race day experience.",
            "date_modified": "2025-03-18T00:00:00.000Z",
            "tags": [
                "running",
                "half-marathon",
                "nyc",
                "charity",
                "fitness",
                "personal-story",
                "fundraising",
                "race-recap",
                "endurance"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/the-10-trillion-openbb-copilot-validation",
            "content_html": "<p align=\"center\"><img width=\"900\" src=\"https://didierlopes.com/blog/2025-03-11-the-10-trillion-openbb-copilot-validation.webp\"></p>\n<p>At the recent AI Engineering Summit, BlackRock unveiled their Aladdin Copilot - a platform remarkably similar to what we've built at OpenBB, but with a key difference.</p>\n<p>While they've invested massive resources into building a closed system, we've created an open-source solution that achieves the same goals: multi-application support, seamless agent integration, explainable AI, and enterprise-grade security. Here's a deep dive into how the world's largest asset manager validated our approach to AI-powered financial workflows.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>On Friday 21st, I attended the <a href=\"https://www.ai.engineer/summit/2025\" target=\"_blank\" rel=\"noopener noreferrer\">AI Engineering Summit</a> from @swyx and Ben. If you're working in the agentic space, this is arguably one of the best conferences available.</p>\n<p>One presentation that particularly caught my attention was BlackRock's session about their Aladdin Copilot. While I can't share the presentation materials as they're conference-exclusive, what I saw left me incredibly bullish about OpenBB's direction.</p>\n<p align=\"center\"><img width=\"900\" src=\"https://didierlopes.com/blog/2025-03-11-the-10-trillion-openbb-copilot-validation_1.webp\"></p>\n<p>Here's why: BlackRock's copilot is remarkably similar to what we've built at OpenBB - but with 1% of their resources and one major distinction.</p>\n<p>Let's dive into the striking similarities first.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"not-a-single-workflow-but-multiple-applications\">Not a single workflow, but multiple applications<a href=\"https://didierlopes.com/blog/the-10-trillion-openbb-copilot-validation#not-a-single-workflow-but-multiple-applications\" class=\"hash-link\" aria-label=\"Direct link to Not a single workflow, but multiple applications\" title=\"Direct link to Not a single workflow, but multiple applications\">​</a></h2>\n<p>BlackRock's Aladdin platform centers heavily on Portfolio - enabling users to handle portfolio construction, management, and monitoring.</p>\n<p>In contrast, OpenBB's Workspace functions as an open playground. While it certainly handles portfolio management (as demonstrated in <a href=\"https://www.youtube.com/watch?v=K80ayaZYyk4\" target=\"_blank\" rel=\"noopener noreferrer\">this example</a>), it extends far beyond that. Our platform supports risk management, equity/crypto/macro research, ideation, ranking, client advisory, and even compliance workflows.</p>\n<p align=\"center\"><img width=\"900\" src=\"https://didierlopes.com/blog/2025-03-11-the-10-trillion-openbb-copilot-validation_2.webp\"></p>\n<p>This versatility stems from our workspace architecture where users build on their own data. The flexible widget creation system can accommodate virtually any workflow - provided users have the necessary data.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"not-a-single-chatting-interface-the-agent-is-on-the-side-and-is-invoked-when-needed\">Not a single chatting interface, the agent is on the side and is invoked when needed<a href=\"https://didierlopes.com/blog/the-10-trillion-openbb-copilot-validation#not-a-single-chatting-interface-the-agent-is-on-the-side-and-is-invoked-when-needed\" class=\"hash-link\" aria-label=\"Direct link to Not a single chatting interface, the agent is on the side and is invoked when needed\" title=\"Direct link to Not a single chatting interface, the agent is on the side and is invoked when needed\">​</a></h2>\n<p>This is a hill I'm willing to die on.</p>\n<p>For the most part, analysts and PMs don't want a chat-only interface for their daily work. I wrote about this extensively <a href=\"https://openbb.co/blog/why-chat-only-ai-financial-assistants-are-not-the-answer-you-might-think-they-are\" target=\"_blank\" rel=\"noopener noreferrer\">8 months ago</a>, and my conviction has only strengthened.</p>\n<p>BlackRock appears to share this view. Their agentic copilot acts as a sidebar to the main interface, allowing users to query dashboard data and quickly validate information without disrupting their workflow.</p>\n<p>Seeing this in their demo was genuinely shocking - it looked remarkably similar to what we've had in OpenBB for over a year now. It's validating to see the world's largest asset manager (with 20k employees) arriving at the same conclusions we did.</p>\n<p align=\"center\"><img width=\"900\" src=\"https://didierlopes.com/blog/2025-03-11-the-10-trillion-openbb-copilot-validation_3.webp\"></p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"explainability\">Explainability<a href=\"https://didierlopes.com/blog/the-10-trillion-openbb-copilot-validation#explainability\" class=\"hash-link\" aria-label=\"Direct link to Explainability\" title=\"Direct link to Explainability\">​</a></h2>\n<p>Both platforms prioritize data transparency. Every copilot response that references dashboard data clearly highlights its source. This enables users to validate LLM outputs and trace information back to its origin, maintaining trust and accountability.</p>\n<p>An example of how it can highlight sentence or table level in unstructured document:</p>\n<p align=\"center\"><img width=\"900\" src=\"https://didierlopes.com/blog/2025-03-11-the-10-trillion-openbb-copilot-validation_4.webp\"></p>\n<p>An example of how it can highlight the widget origin that was used to answer to the prompt:</p>\n<p align=\"center\"><img width=\"900\" src=\"https://didierlopes.com/blog/2025-03-11-the-10-trillion-openbb-copilot-validation_5.webp\"></p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"secure-environment-first-approach\">Secure environment first approach<a href=\"https://didierlopes.com/blog/the-10-trillion-openbb-copilot-validation#secure-environment-first-approach\" class=\"hash-link\" aria-label=\"Direct link to Secure environment first approach\" title=\"Direct link to Secure environment first approach\">​</a></h2>\n<p>This is non-negotiable in finance, where both data and prompts can be competitive advantages. Our president, <a href=\"https://www.linkedin.com/in/heidisjohnson/\" target=\"_blank\" rel=\"noopener noreferrer\">Heidi Jonhson</a>, recently detailed our approach to this in our <a href=\"https://openbb.co/blog/run-openbb-on-premises-and-be-in-control-of-your-data-and-UI\" target=\"_blank\" rel=\"noopener noreferrer\">on-prem announcement</a>.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"architecture\">Architecture<a href=\"https://didierlopes.com/blog/the-10-trillion-openbb-copilot-validation#architecture\" class=\"hash-link\" aria-label=\"Direct link to Architecture\" title=\"Direct link to Architecture\">​</a></h2>\n<p>While I can't share specifics from BlackRock's presentation, I can explain OpenBB's architecture, which appears to follow identical principles.</p>\n<p>Our OpenBB Copilot acts as an orchestrator, gathering context from three main sources (in order of importance):</p>\n<ol>\n<li><strong>In-context</strong>: Either attached files or explicitly referenced data widgets</li>\n<li><strong>Dashboard</strong>: Data currently visible in the dashboard</li>\n<li><strong>Product-wide</strong>: Connected to the workspace but not visible</li>\n</ol>\n<br>\n<p align=\"center\"><img width=\"900\" src=\"https://didierlopes.com/blog/2025-03-11-the-10-trillion-openbb-copilot-validation_6.webp\"></p>\n<p>This context exists in the form of widgets, and there can be thousands! In the case of BlackRock, they refer to this as Plugin Registry.</p>\n<p align=\"center\"><img width=\"900\" src=\"https://didierlopes.com/blog/2025-03-11-the-10-trillion-openbb-copilot-validation_7.webp\"></p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"what-is-a-widget\">What is a widget?<a href=\"https://didierlopes.com/blog/the-10-trillion-openbb-copilot-validation#what-is-a-widget\" class=\"hash-link\" aria-label=\"Direct link to What is a widget?\" title=\"Direct link to What is a widget?\">​</a></h3>\n<p>In our system, a widget combines:</p>\n<ul>\n<li>Data origin (API endpoint, static file, SQL query with DB connection, etc)</li>\n<li>The parameters that can be modified to query a variation of the data</li>\n<li>Metadata (title, description, category, sub-category, and source)</li>\n</ul>\n<p>The metadata enables our copilot to identify and utilize appropriate widget based on user prompts, by controlling the widget through its parameters.</p>\n<p align=\"center\"><img width=\"900\" src=\"https://didierlopes.com/blog/2025-03-11-the-10-trillion-openbb-copilot-validation_8.webp\"></p>\n<p>You can think of these widgets effectively as tools that are rendered on our workspace. Therefore, our agent can call different widgets to retrieve the data it needs to reply more effectively to the user.</p>\n<p>For a deeper dive into this architecture, check out my recent <a href=\"https://www.youtube.com/watch?v=gH1mMtRa84Y\" target=\"_blank\" rel=\"noopener noreferrer\">10-minute presentation</a> or the blog <a href=\"https://didierlopes.com/blog/2025-03-01-how-function-calling-and-context-aware-ai-shapes-openbb\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"distinction\">Distinction<a href=\"https://didierlopes.com/blog/the-10-trillion-openbb-copilot-validation#distinction\" class=\"hash-link\" aria-label=\"Direct link to Distinction\" title=\"Direct link to Distinction\">​</a></h2>\n<p>So what is the main distinction?</p>\n<p>How Open we are.</p>\n<p align=\"center\"><img width=\"1200\" src=\"https://didierlopes.com/blog/2025-03-11-the-10-trillion-openbb-copilot-validation_9.webp\"></p>\n<p>We have an open source data integration framework that enables any firm from bringing any type of data into our product.</p>\n<p>We have an open source agentic framework that enables any firm to build their own agent (even one running locally).</p>\n<p>And we intend to open source much more.</p>\n<p>We believe in a future where each firm will build their own tools on top of the most popular open source infra.</p>\n<p>If you fall under that umbrella, reach out.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/the-10-trillion-openbb-copilot-validation",
            "title": "The $10 trillion OpenBB Copilot validation",
            "summary": "At the recent AI Engineering Summit, BlackRock unveiled their Aladdin Copilot - a platform remarkably similar to what we've built at OpenBB, but with a key difference. While they've invested massive resources into building a closed system, we've created an open-source solution that achieves the same goals: multi-application support, seamless agent integration, explainable AI, and enterprise-grade security. Here's a deep dive into how the world's largest asset manager validated our approach to AI-powered financial workflows.",
            "date_modified": "2025-03-11T00:00:00.000Z",
            "tags": [
                "openbb",
                "blackrock",
                "copilot",
                "enterprise",
                "agent",
                "widgets",
                "architecture",
                "open-source",
                "finance",
                "portfolio",
                "security"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/proactive-agents-are-the-future-of-ai-in-finance",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-03-07-proactive-agents-are-the-future-of-ai-in-finance.webp\"></p>\n<p>How AI is evolving from reactive to proactive in financial services, and why this shift will transform how investors discover opportunities and generate alpha.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>Imagine waking up to find your AI assistant has already analyzed overnight market movements, identified three potential investment opportunities aligned with your strategy, and prepared a briefing on key economic indicators that might impact your portfolio today. This isn't science fiction—it's the imminent future of AI in finance.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"the-evolution-of-financial-ai-from-reactive-to-proactive\">The Evolution of Financial AI: From Reactive to Proactive<a href=\"https://didierlopes.com/blog/proactive-agents-are-the-future-of-ai-in-finance#the-evolution-of-financial-ai-from-reactive-to-proactive\" class=\"hash-link\" aria-label=\"Direct link to The Evolution of Financial AI: From Reactive to Proactive\" title=\"Direct link to The Evolution of Financial AI: From Reactive to Proactive\">​</a></h2>\n<p>This week I was asked the question \"Where is OpenBB with AI next year?\".</p>\n<p>Our play here is clear, we are the Enterprise UI that lives between data and AI.</p>\n<p>So when someone asks this question, they are ultimately asking \"What will be possible to do on OpenBB as models get better and cheaper\".</p>\n<p>And I think that it all comes down to: <strong>Reactive VS Proactive</strong></p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"the-current-state-reactive-ai\">The Current State: Reactive AI<a href=\"https://didierlopes.com/blog/proactive-agents-are-the-future-of-ai-in-finance#the-current-state-reactive-ai\" class=\"hash-link\" aria-label=\"Direct link to The Current State: Reactive AI\" title=\"Direct link to The Current State: Reactive AI\">​</a></h3>\n<p>Today, LLMs/agents/AI is reactive for the most part.</p>\n<p>It requires users to have a clear intent on what they want the LLM to do, they are required to be prompted (pun intended). You ask a question, the AI answers. You request an analysis, the AI delivers. The interaction is fundamentally user-initiated and bounded by the specificity of your requests.</p>\n<p>This reactive paradigm, while powerful, places the burden of discovery on the human user. You need to know what to ask for, when to ask for it, and how to frame your questions.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"the-future-state-proactive-ai\">The Future State: Proactive AI<a href=\"https://didierlopes.com/blog/proactive-agents-are-the-future-of-ai-in-finance#the-future-state-proactive-ai\" class=\"hash-link\" aria-label=\"Direct link to The Future State: Proactive AI\" title=\"Direct link to The Future State: Proactive AI\">​</a></h3>\n<p>However, what happens when models get better and cheaper and they have an interface that has access to all their data in one place?</p>\n<p>Simple.</p>\n<p>It can scan the data every few seconds and generate investment ideas, find alpha and truly act like a partner. A proactive AI agent might:</p>\n<ul>\n<li>Alert you to unusual trading patterns in a sector you're tracking</li>\n<li>Identify correlations between market events and your portfolio performance</li>\n<li>Suggest portfolio rebalancing based on changing market conditions</li>\n<li>Highlight emerging trends before they become mainstream investment theses</li>\n</ul>\n<p>More importantly, as the agent starts to engage with the user, we will be able to provide feedback to the model: \"this wasn't a good idea because of X\", \"semi-conductors are not part of my mandate\", ... and these models will adapt to become more personalized.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"real-world-applications\">Real-World Applications<a href=\"https://didierlopes.com/blog/proactive-agents-are-the-future-of-ai-in-finance#real-world-applications\" class=\"hash-link\" aria-label=\"Direct link to Real-World Applications\" title=\"Direct link to Real-World Applications\">​</a></h2>\n<p>Imagine a portfolio manager receiving an alert: \"Three companies in your watchlist have shown unusual options activity following yesterday's Fed announcement. Based on your previous trading patterns, this may represent an opportunity in line with your contrarian strategy.\"</p>\n<p>Or consider a risk analyst being notified: \"We've detected a 3.2 standard deviation move in correlation between your two largest positions. Here's an analysis of what might be driving this change and three potential hedging strategies.\"</p>\n<p>The exciting thing?</p>\n<p>We aren't that far off from this being a reality.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"the-openbb-vision\">The OpenBB Vision<a href=\"https://didierlopes.com/blog/proactive-agents-are-the-future-of-ai-in-finance#the-openbb-vision\" class=\"hash-link\" aria-label=\"Direct link to The OpenBB Vision\" title=\"Direct link to The OpenBB Vision\">​</a></h2>\n<p>At OpenBB, we're building the infrastructure to make this proactive AI future possible. By creating a unified interface between financial data and AI capabilities, we're enabling the next generation of intelligent financial assistants that don't just answer questions—they anticipate needs.</p>\n<p>This is how I envision the future:</p>\n<div class=\"flex place-items-center justify-center items-center rounded-sm mx-auto\"><iframe src=\"https://www.youtube.com/embed/xTvaks7EDh0?si=szd8RNFyMD_SPAHm\" width=\"1000\" height=\"500\"></iframe></div>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"what-this-means-for-you\">What this means for you<a href=\"https://didierlopes.com/blog/proactive-agents-are-the-future-of-ai-in-finance#what-this-means-for-you\" class=\"hash-link\" aria-label=\"Direct link to What this means for you\" title=\"Direct link to What this means for you\">​</a></h2>\n<p>The shift from reactive to proactive AI will fundamentally change how financial professionals work:</p>\n<ol>\n<li><strong>Time efficiency</strong>: Less time spent on routine data gathering and more time on high-value decision making</li>\n<li><strong>Expanded opportunity set</strong>: Discover investment ideas outside your usual information channels</li>\n<li><strong>Personalized intelligence</strong>: AI that learns your preferences, risk tolerance, and investment style</li>\n<li><strong>Competitive edge</strong>: Early identification of market shifts and anomalies</li>\n</ol>\n<br>\n<p>The future of finance isn't just about having better answers—it's about having an AI partner that asks better questions.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/proactive-agents-are-the-future-of-ai-in-finance",
            "title": "Proactive Agents Are the Future of AI in Finance",
            "summary": "How AI is evolving from reactive to proactive in financial services, and why this shift will transform how investors discover opportunities and generate alpha.",
            "date_modified": "2025-03-07T00:00:00.000Z",
            "tags": [
                "openbb",
                "financial-services",
                "ai",
                "investment",
                "proactive-agents",
                "agents",
                "future"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/my-key-takeaways-from-institutional-investor-conference",
            "content_html": "<p align=\"center\"><img width=\"900\" src=\"https://didierlopes.com/blog/2025-03-05-my-key-takeaways-from-institutional-investor-conference.webp\"></p>\n<p>Key insights from financial services technology leaders on AI adoption, including build vs. buy strategies, data privacy concerns, technology adoption divides, and the challenges of moving from prototypes to production-ready solutions.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>I just returned from an insightful financial services technology conference where CTOs, CIOs, and technology leaders shared their perspectives on AI.</p>\n<p>I was on the stage on the topic of \"Autonomous Agents — The Next Step in AI Applications?\" which was one of my favorite panels that I've ever done.</p>\n<p>This allowed me to have extremely insigthful conversations with industry leaders managing dozens to hundreds of billions of dollars in AUM.</p>\n<p>Here are the most valuable insights I gathered:</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"the-build-vs-buy-evolution\">The build vs. buy evolution<a href=\"https://didierlopes.com/blog/my-key-takeaways-from-institutional-investor-conference#the-build-vs-buy-evolution\" class=\"hash-link\" aria-label=\"Direct link to The build vs. buy evolution\" title=\"Direct link to The build vs. buy evolution\">​</a></h2>\n<p>Financial institutions increasingly prefer building over buying complete solutions. Most follow a hybrid approach—purchasing foundational technology but building customized layers on top. The consensus is that this approach reduces complexity in the long term while avoiding vendor lock-in.</p>\n<blockquote>\n<p><strong>OpenBB hat on</strong>: This is one of the reasons we love open source - it gives users a third option: building on top of an infrastructure that is continuously maintained and improved, allowing firms to focus solely on their workflows.</p>\n</blockquote>\n<br>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"ai-adoption-challenges\">AI adoption challenges<a href=\"https://didierlopes.com/blog/my-key-takeaways-from-institutional-investor-conference#ai-adoption-challenges\" class=\"hash-link\" aria-label=\"Direct link to AI adoption challenges\" title=\"Direct link to AI adoption challenges\">​</a></h2>\n<p>Despite the hype, financial services firms struggle with AI implementation, primarily due to unclear use cases. There is no dominant AI product in the industry, and most organizations cautiously use general tools under strict controls.</p>\n<blockquote>\n<p><strong>OpenBB hat on</strong>: This is a great sign that we are still early, and there isn't yet a clear winner in AI financial products. It also indicates that companies need to invest capital in educating the market—not just about their products (I'm guilty of this) but about the workflows that AI can enable. (Luckily, <a href=\"https://www.linkedin.com/in/ihsan-erman-saracgil-42628454/\" target=\"_blank\" rel=\"noopener noreferrer\">Ihsan</a> joined the team recently, and I've seen him build full workflows for clients like this <a href=\"https://www.youtube.com/watch?v=JTlyU6HdWjQ\" target=\"_blank\" rel=\"noopener noreferrer\">earnings workflow</a> solely on OpenBB. If you're looking for something specific, he's the person to ask!)</p>\n</blockquote>\n<br>\n<p align=\"center\"><img width=\"900\" src=\"https://didierlopes.com/blog/2025-03-05-my-key-takeaways-from-institutional-investor-conference_1.webp\"></p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"data-privacy-concerns-without-local-solutions\">Data privacy concerns without local solutions<a href=\"https://didierlopes.com/blog/my-key-takeaways-from-institutional-investor-conference#data-privacy-concerns-without-local-solutions\" class=\"hash-link\" aria-label=\"Direct link to Data privacy concerns without local solutions\" title=\"Direct link to Data privacy concerns without local solutions\">​</a></h2>\n<p>Significant concern was expressed about data leakage when using AI tools, with strict policies such as \"no credit card swipes for AI tools\" and \"turn off uploads\" being common. Interestingly, no one mentioned running open-weight models locally, a solution that would address these privacy concerns by keeping data in-house. This represents a major market education opportunity, as firms are worried about data leaving their environment but aren't aware of alternatives to cloud-based AI services.</p>\n<blockquote>\n<p><strong>OpenBB hat on</strong>: This one really surprised me. It may be because most products currently follow a traditional SaaS model. However, I saw a clear need for on-prem/VPC deployments where firms run open-weight models locally with zero data leakage. We can do this — and we might be one of the few products on the market that can today.</p>\n</blockquote>\n<br>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"technology-adoption-divide\">Technology adoption divide<a href=\"https://didierlopes.com/blog/my-key-takeaways-from-institutional-investor-conference#technology-adoption-divide\" class=\"hash-link\" aria-label=\"Direct link to Technology adoption divide\" title=\"Direct link to Technology adoption divide\">​</a></h2>\n<p>A clear divide exists between technology resistors and embracers. Some professionals cling to legacy tools and manual processes, seemingly to preserve their relevance. Meanwhile, AI adopters are achieving remarkable productivity gains, quickly building React applications, simulations, and analytical tools.</p>\n<blockquote>\n<p><strong>OpenBB hat on</strong>:  This trend was expected. I've personally experienced how AI has dramatically increased my coding efficiency. As the cost of building continues to approach zero, we'll see exponential opportunities to automate workflows. Talent with AI expertise won't just deliver 2-3x value for their firms but potentially 10x or more. This represents both a challenge and an opportunity for organizations ready to embrace these new capabilities.</p>\n</blockquote>\n<br>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"prototype-to-production-gap\">Prototype-to-production gap<a href=\"https://didierlopes.com/blog/my-key-takeaways-from-institutional-investor-conference#prototype-to-production-gap\" class=\"hash-link\" aria-label=\"Direct link to Prototype-to-production gap\" title=\"Direct link to Prototype-to-production gap\">​</a></h2>\n<p>A common challenge is bridging the gap between 70% done prototypes and enterprise-ready solutions. AI enables rapid development and impressive demos, but the real challenge is implementing governance, security, compliance, and scalability for production environments. Organizations need talent that can leverage AI for rapid innovation while also understanding enterprise requirements to bring projects to completion.</p>\n<blockquote>\n<p><strong>OpenBB hat on</strong>: This reality is particularly evident in development practices. A quick demo in Streamlit can be built in minutes—great for rapid prototyping. However, such solutions rarely meet enterprise standards. Developing production-ready features like RBAC, SSO, administrative controls, sharing capabilities, comprehensive logging, and reporting systems requires an entirely different skill set and approach. We often see firms approaching us after realizing their prototype tools won't scale to meet their long-term strategic objectives.</p>\n</blockquote>\n<br>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"what-this-means-for-openbb\">What this means for OpenBB<a href=\"https://didierlopes.com/blog/my-key-takeaways-from-institutional-investor-conference#what-this-means-for-openbb\" class=\"hash-link\" aria-label=\"Direct link to What this means for OpenBB\" title=\"Direct link to What this means for OpenBB\">​</a></h2>\n<p>OpenBB is uniquely positioned at the intersection of these trends. As an open workspace that supports bring-your-own-data, local AI deployment, and enterprise-grade features, we provide financial institutions with the flexibility to build custom solutions while addressing security concerns and bridging the prototype-to-production gap.</p>\n<p>Our approach aligns perfectly with the industry's evolving needs, making us an ideal partner for forward-thinking financial organizations navigating AI transformation.</p>\n<p>If you want to chat, feel free to e-mail me at didier.lopes[at]openbb.finance.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/my-key-takeaways-from-institutional-investor-conference",
            "title": "My key takeaways from Institutional Investor conference",
            "summary": "Key insights from financial services technology leaders on AI adoption, including build vs. buy strategies, data privacy concerns, technology adoption divides, and the challenges of moving from prototypes to production-ready solutions.",
            "date_modified": "2025-03-05T00:00:00.000Z",
            "tags": [
                "openbb",
                "financial-services",
                "ai-adoption",
                "data-privacy",
                "enterprise-ai",
                "build-vs-buy",
                "open-source",
                "finance",
                "local-deployment"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/building-a-custom-widget-for-my-friends-newsletter",
            "content_html": "<p align=\"center\"><img width=\"900\" src=\"https://didierlopes.com/blog/2025-03-03-building-a-custom-widget-for-my-friends-newsletter.webp\"></p>\n<p>How I built a custom OpenBB widget to save my friend hours of manual work on his newsletter with 190,000+ subscribers.</p>\n<p>The open source code is available <a href=\"https://github.com/DidierRLopes/opening-bell-daily-openbb\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>Last weekend I spoke with my friend <a href=\"https://www.linkedin.com/in/philrosen/\" target=\"_blank\">Phil Rosen</a>.</p>\n<p>He used to work as a Senior Markets Reporter at Business Insider.</p>\n<p>And left to start his own news and research outlet: <a href=\"https://www.openingbelldailynews.com/\" target=\"_blank\">Opening Bell Daily</a>, just over 1 year ago.</p>\n<p>He's been sharing a newsletter everyday since and has crossed over 190,000 subscribers!!!</p>\n<p>Funnily enough, we commented on how we were speaking on a Saturday morning and the weekends are the times where we are the most productive.</p>\n<p>As I was sharing more of OpenBB and how he can utilize it for the content in his newsletter, he shared a table chart that he crafts manually to his audience, which always takes him a significant amount of time to do every single day.</p>\n<p>Well, I wouldn't be an engineer by training if I didn't solve this for him.</p>\n<div class=\"flex place-items-center justify-center items-center rounded-sm mx-auto\"><iframe src=\"https://www.youtube.com/embed/9hQtFL_0NjU?si=oUC-X0XsnKad-V9E\" width=\"1000\" height=\"500\"></iframe></div>\n<p>More than that - to celebrate 1 year of Opening Bell Daily:</p>\n<blockquote>\n<p>Any OpenBB user can add this URL as a custom backend application on OpenBB and have Phil's market snapshot on their screen every day. <a href=\"https://openbb-opening-bell-daily.fly.dev/\" target=\"_blank\" rel=\"noopener noreferrer\">https://openbb-opening-bell-daily.fly.dev</a></p>\n</blockquote>\n<br>\n<p>Or you can also sign up to Phil's newsletter and get it in your inbox along with insightful content, every day!</p>\n<p align=\"center\"><img width=\"900\" src=\"https://didierlopes.com/blog/2025-03-03-building-a-custom-widget-for-my-friends-newsletter_1.webp\"></p>\n<p>PS: I have made this code <a href=\"https://github.com/DidierRLopes/opening-bell-daily-openbb\" target=\"_blank\" rel=\"noopener noreferrer\">open source</a> so others can create their own widgets for OpenBB or get inspired.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/building-a-custom-widget-for-my-friends-newsletter",
            "title": "Building a custom widget for my friends newsletter",
            "summary": "How I built a custom OpenBB widget to save my friend hours of manual work on his newsletter with 190,000+ subscribers.",
            "date_modified": "2025-03-03T00:00:00.000Z",
            "tags": [
                "openbb",
                "widget",
                "automation",
                "open-source",
                "fintech",
                "api",
                "side-project",
                "newsletter"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/how-function-calling-and-context-aware-ai-shapes-openbb",
            "content_html": "<p align=\"center\"><img width=\"900\" src=\"https://didierlopes.com/blog/2025-03-01-how-function-calling-and-context-aware-ai-shapes-openbb.webp\"></p>\n<p>Building on OpenBB's presentation at the Anote AI Day Summit, this post explores how intelligent function calling serves as the cornerstone of our AI-native workspace for data analytics.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>I recently had the opportunity to present our OpenBB Copilot and how most of what it does is function calling, in the Anote AI Day Summit: <a href=\"https://www.youtube.com/watch?v=gH1mMtRa84Y\" target=\"_blank\" rel=\"noopener noreferrer\">It is All Function Calling - Anote AI Day Summit 2025</a>.</p>\n<p>This blog post is a similar presentation in text-written format.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"our-vision-for-the-openbb-workspace\">Our vision for the OpenBB Workspace<a href=\"https://didierlopes.com/blog/how-function-calling-and-context-aware-ai-shapes-openbb#our-vision-for-the-openbb-workspace\" class=\"hash-link\" aria-label=\"Direct link to Our vision for the OpenBB Workspace\" title=\"Direct link to Our vision for the OpenBB Workspace\">​</a></h2>\n<p>At the core of our product is the OpenBB workspace, a fully customizable dashboard where users can control their data visualization and analysis. The middle section shows a dashboard that you can fully customize with widgets containing relevant data widgets. We've designed it with a practical sidebar for managing dashboards, folder organization, sharing capabilities, templates, and data connections.</p>\n<p align=\"center\"><img width=\"900\" src=\"https://didierlopes.com/blog/2025-03-01-how-function-calling-and-context-aware-ai-shapes-openbb_1.webp\"></p>\n<p>But what I'm going to talk about is our agentic sidebar on the right. This is effectively your AI agent that works as an analyst with access to all the data inside the product. And this is where our implementation of function calling becomes crucial.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"context-is-key\">Context is key<a href=\"https://didierlopes.com/blog/how-function-calling-and-context-aware-ai-shapes-openbb#context-is-key\" class=\"hash-link\" aria-label=\"Direct link to Context is key\" title=\"Direct link to Context is key\">​</a></h2>\n<p>We've developed three ways to provide context to our Copilot:</p>\n<ol>\n<li><strong>Explicit context</strong>: We've added a simple button on the top right of widgets that allows users to directly add them to the Copilot's context. You can also simply drop files into the Copilot window.</li>\n</ol>\n<br>\n<p align=\"center\"><img width=\"900\" src=\"https://didierlopes.com/blog/2025-03-01-how-function-calling-and-context-aware-ai-shapes-openbb_2.webp\"></p>\n<ol start=\"2\">\n<li><strong>Dashboard context</strong>: In this case, the Copilot can access all data present on the current dashboard and will then inform the user which widgets were used.</li>\n</ol>\n<br>\n<p align=\"center\"><img width=\"900\" src=\"https://didierlopes.com/blog/2025-03-01-how-function-calling-and-context-aware-ai-shapes-openbb_3.webp\"></p>\n<ol start=\"3\">\n<li><strong>Global context</strong>: Through a feature flag, users can also enable searching across all widgets within the workspace.</li>\n</ol>\n<br>\n<p align=\"center\"><img width=\"900\" src=\"https://didierlopes.com/blog/2025-03-01-how-function-calling-and-context-aware-ai-shapes-openbb_4.webp\"></p>\n<p align=\"center\"><img width=\"900\" src=\"https://didierlopes.com/blog/2025-03-01-how-function-calling-and-context-aware-ai-shapes-openbb_5.webp\"></p>\n<p>What's important is how we've prioritized these: explicit context takes precedence, followed by dashboard context, and then global context.</p>\n<p align=\"center\"><img width=\"900\" src=\"https://didierlopes.com/blog/2025-03-01-how-function-calling-and-context-aware-ai-shapes-openbb_6.webp\"></p>\n<p>It's similar to an analyst's process—you begin by examining the document in front of you, then assess the items on your desk, and finally consider your wider resources, such as Google Drive or Slack.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"the-power-of-widget-metadata\">The power of widget metadata<a href=\"https://didierlopes.com/blog/how-function-calling-and-context-aware-ai-shapes-openbb#the-power-of-widget-metadata\" class=\"hash-link\" aria-label=\"Direct link to The power of widget metadata\" title=\"Direct link to The power of widget metadata\">​</a></h3>\n<p>One of our key innovations is our metadata system.</p>\n<p align=\"center\"><img width=\"900\" src=\"https://didierlopes.com/blog/2025-03-01-how-function-calling-and-context-aware-ai-shapes-openbb_7.webp\"></p>\n<p>Each widget in our product has what we call \"widget metadata\" composed of five components:</p>\n<ul>\n<li>Title</li>\n<li>Category</li>\n<li>Subcategory</li>\n<li>Description</li>\n<li>Data source</li>\n</ul>\n<p>We convert this metadata into embeddings and compare it against user prompts to determine which functions the Copilot should access. This allows us to scale effectively while maintaining accuracy, especially since there can be literally thousands of data widgets. Due to the metadata, widgets are only invoked when a user triggers a relevant prompt.</p>\n<p align=\"center\"><img width=\"900\" src=\"https://didierlopes.com/blog/2025-03-01-how-function-calling-and-context-aware-ai-shapes-openbb_8.webp\"></p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"function-calling-in-practice\">Function Calling in practice<a href=\"https://didierlopes.com/blog/how-function-calling-and-context-aware-ai-shapes-openbb#function-calling-in-practice\" class=\"hash-link\" aria-label=\"Direct link to Function Calling in practice\" title=\"Direct link to Function Calling in practice\">​</a></h2>\n<p>Let me share some real examples of how this works.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"basic-function-calls\">Basic function calls<a href=\"https://didierlopes.com/blog/how-function-calling-and-context-aware-ai-shapes-openbb#basic-function-calls\" class=\"hash-link\" aria-label=\"Direct link to Basic function calls\" title=\"Direct link to Basic function calls\">​</a></h3>\n<p>When analyzing unstructured data like market reports, our Copilot can extract specific information without parameter changes:</p>\n<p align=\"center\"><img width=\"900\" src=\"https://didierlopes.com/blog/2025-03-01-how-function-calling-and-context-aware-ai-shapes-openbb_9.webp\"></p>\n<p>Copilot understands from widget metadata that the user requires information from it and queries it:</p>\n<p align=\"center\"><img width=\"900\" src=\"https://didierlopes.com/blog/2025-03-01-how-function-calling-and-context-aware-ai-shapes-openbb_10.webp\"></p>\n<p>In turn that data is utilized to answer the prompt:</p>\n<p align=\"center\"><img width=\"900\" src=\"https://didierlopes.com/blog/2025-03-01-how-function-calling-and-context-aware-ai-shapes-openbb_11.webp\"></p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"parameter-modified-calls\">Parameter-modified calls<a href=\"https://didierlopes.com/blog/how-function-calling-and-context-aware-ai-shapes-openbb#parameter-modified-calls\" class=\"hash-link\" aria-label=\"Direct link to Parameter-modified calls\" title=\"Direct link to Parameter-modified calls\">​</a></h3>\n<p>We can handle cases where users want to switch contexts.</p>\n<p>For instance, even if you're looking at Apple news, you can ask about Palantir, and our system will automatically adjust the parameters:</p>\n<p align=\"center\"><img width=\"900\" src=\"https://didierlopes.com/blog/2025-03-01-how-function-calling-and-context-aware-ai-shapes-openbb_12.webp\"></p>\n<p>Copilot understands from widget metadata that the user requires information from it and queries it:</p>\n<p align=\"center\"><img width=\"900\" src=\"https://didierlopes.com/blog/2025-03-01-how-function-calling-and-context-aware-ai-shapes-openbb_13.webp\"></p>\n<p>But, not as is. It requires updating input parameters accordingly (symbol and dates):</p>\n<p align=\"center\"><img width=\"900\" src=\"https://didierlopes.com/blog/2025-03-01-how-function-calling-and-context-aware-ai-shapes-openbb_14.webp\"></p>\n<p>In turn, that data is utilized to answer the prompt:</p>\n<p align=\"center\"><img width=\"900\" src=\"https://didierlopes.com/blog/2025-03-01-how-function-calling-and-context-aware-ai-shapes-openbb_15.webp\"></p>\n<p>Finally, the utilized widget (with updated parameters) can be added to the dashboard seamlessly.</p>\n<p align=\"center\"><img width=\"900\" src=\"https://didierlopes.com/blog/2025-03-01-how-function-calling-and-context-aware-ai-shapes-openbb_16.webp\"></p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"complex-analysis\">Complex analysis<a href=\"https://didierlopes.com/blog/how-function-calling-and-context-aware-ai-shapes-openbb#complex-analysis\" class=\"hash-link\" aria-label=\"Direct link to Complex analysis\" title=\"Direct link to Complex analysis\">​</a></h3>\n<p>For more sophisticated tasks like analyzing futures contracts for arbitrage opportunities, our Copilot can make multiple function calls, process the data, and create visualizations.</p>\n<p align=\"center\"><img width=\"900\" src=\"https://didierlopes.com/blog/2025-03-01-how-function-calling-and-context-aware-ai-shapes-openbb_17.webp\"></p>\n<p>Copilot understands from widget metadata that the user requires information from it, with updated parameters, and queries it.</p>\n<p align=\"center\"><img width=\"900\" src=\"https://didierlopes.com/blog/2025-03-01-how-function-calling-and-context-aware-ai-shapes-openbb_18.webp\"></p>\n<p>In turn, that data is utilized to answer the prompt...</p>\n<p align=\"center\"><img width=\"900\" src=\"https://didierlopes.com/blog/2025-03-01-how-function-calling-and-context-aware-ai-shapes-openbb_19.webp\"></p>\n<p>and creating a chart like the user asked:</p>\n<p align=\"center\"><img width=\"900\" src=\"https://didierlopes.com/blog/2025-03-01-how-function-calling-and-context-aware-ai-shapes-openbb_20.webp\"></p>\n<p>Finally, the resulting artifact (in this case, a chart) can be added to the dashboard:</p>\n<p align=\"center\"><img width=\"900\" src=\"https://didierlopes.com/blog/2025-03-01-how-function-calling-and-context-aware-ai-shapes-openbb_21.webp\"></p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"verification-and-output\">Verification and output<a href=\"https://didierlopes.com/blog/how-function-calling-and-context-aware-ai-shapes-openbb#verification-and-output\" class=\"hash-link\" aria-label=\"Direct link to Verification and output\" title=\"Direct link to Verification and output\">​</a></h2>\n<p>We're particularly proud of our verification system for the Copilot. It allows users to:</p>\n<ul>\n<li>See the step-by-step reasoning</li>\n<li>Access data sources through citations</li>\n<li>Add source widgets to their dashboard</li>\n<li>Get highlights of specific data references</li>\n</ul>\n<p>The output can be added directly to the dashboard as new widgets, creating a seamless workflow from query to visualization to presentation.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"looking-forward\">Looking forward<a href=\"https://didierlopes.com/blog/how-function-calling-and-context-aware-ai-shapes-openbb#looking-forward\" class=\"hash-link\" aria-label=\"Direct link to Looking forward\" title=\"Direct link to Looking forward\">​</a></h2>\n<p>We've built something that I believe truly changes how people can interact with financial data, and we're just getting started. The combination of intelligent function calling, context awareness, and user-friendly interface is making sophisticated financial analysis more accessible than ever before.</p>\n<p>You can get started for free at <a href=\"http://pro.openbb.co/\" target=\"_blank\" rel=\"noopener noreferrer\">pro.openbb.co</a>.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/how-function-calling-and-context-aware-ai-shapes-openbb",
            "title": "How function calling and context-aware AI shapes OpenBB",
            "summary": "Building on OpenBB's presentation at the Anote AI Day Summit, this post explores how intelligent function calling serves as the cornerstone of our AI-native workspace for data analytics.",
            "date_modified": "2025-03-01T00:00:00.000Z",
            "tags": [
                "openbb",
                "ai",
                "llm",
                "function-calling",
                "agent",
                "copilot",
                "data-analytics",
                "financial-analysis"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/ui-layer-is-the-next-big-frontier",
            "content_html": "<p align=\"center\"><img width=\"900\" src=\"https://didierlopes.com/blog/2025-02-25-ui-layer-is-the-next-big-frontier.webp\"></p>\n<p>A deep dive into why the UI layer represents the next major frontier in financial technology.</p>\n<p>While the industry has heavily invested in data, the user interface remains a critical yet overlooked bridge between raw information and actionable intelligence. This piece explores how OpenBB is leading the charge in revolutionizing how financial professionals interact with data.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<blockquote>\n<p><em><strong>Note</strong>: This post was written after reading the <a href=\"https://open.substack.com/pub/theterminalist/p/10000x-bloombergs-return-and-why\" target=\"_blank\" rel=\"noopener noreferrer\">10,000x. Bloomberg's return and why financial data is so darn lucrative</a> from the <a href=\"https://x.com/TheTerminalist\" target=\"_blank\" rel=\"noopener noreferrer\">TheTerminalist</a>.</em></p>\n</blockquote>\n<br>\n<p>For decades, financial research and analytics have been locked in complex, fragmented workflows.</p>\n<p>Firms rely on an ever-expanding set of data providers, yet the tools they use to extract value from that data remain clunky and disconnected. The market has seen heavy investment in solving the data layer, but little attention has been paid to the UI layer—the critical bridge between raw data and actionable intelligence.</p>\n<p><strong>Why?</strong></p>\n<p>Because building intuitive financial UIs requires a rare combination of deep market knowledge and modern technical expertise.</p>\n<p>Most financial professionals excel at understanding markets but aren't software engineers, while most software engineers don't have extensive financial domain experience.</p>\n<p>This expertise gap has led to a reliance on familiar but limited tools like Excel, or third party desktop apps.</p>\n<p>But the shift is happening. With AI dramatically reducing the cost and complexity of building software, the barriers between financial expertise and technical implementation are finally breaking down.</p>\n<p>And OpenBB is here to bootstrap that revolution.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"the-challenge-at-the-delivery-stage\">The challenge at the delivery stage<a href=\"https://didierlopes.com/blog/ui-layer-is-the-next-big-frontier#the-challenge-at-the-delivery-stage\" class=\"hash-link\" aria-label=\"Direct link to The challenge at the delivery stage\" title=\"Direct link to The challenge at the delivery stage\">​</a></h2>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-02-25-ui-layer-is-the-next-big-frontier_1.webp\"></p><p align=\"center\" class=\"mt-1\" style=\"font-size:0.75em\"></p><div>Excerpt from <a href=\"https://x.com/TheTerminalist\" target=\"_blank\" rel=\"noopener noreferrer\">TheTerminalist</a>'s blogpost: </div><a href=\"https://open.substack.com/pub/theterminalist/p/10000x-bloombergs-return-and-why\" target=\"_blank\" rel=\"noopener noreferrer\">10,000x. Bloomberg's return and why financial data is so darn lucrative</a><p></p><p></p>\n<p>The finance and AI space is cost-intensive.</p>\n<p>Innovation requires deep R&amp;D, technical expertise, and the ability to handle highly flexible yet complex workflows. This is why many past attempts to improve financial research software have been set up for failure - they focused on owning or controlling data rather than optimizing how users interact with it.</p>\n<p>The real opportunity lies at the application layer.</p>\n<p>Data is increasingly commoditized, and as financial marketplaces grow, the real value is shifting towards how that data is consumed.</p>\n<p>Intelligence - how insights are generated, refined, and acted upon—is where the competitive edge lies.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"why-the-ui-layer-has-been-overlooked\">Why the UI layer has been overlooked<a href=\"https://didierlopes.com/blog/ui-layer-is-the-next-big-frontier#why-the-ui-layer-has-been-overlooked\" class=\"hash-link\" aria-label=\"Direct link to Why the UI layer has been overlooked\" title=\"Direct link to Why the UI layer has been overlooked\">​</a></h2>\n<p>Building a beloved financial desktop application isn't just about better charts or a sleeker interface. It requires a fundamental rethink of how users interact with their data.</p>\n<p>The industry's reliance on fragmented workflows has meant that firms have learned to tolerate inefficiencies, simply because \"it works.\"</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-02-25-ui-layer-is-the-next-big-frontier_2.webp\"></p><p align=\"center\" class=\"mt-1\" style=\"font-size:0.75em\"></p><div>Excerpt from <a href=\"https://x.com/TheTerminalist\" target=\"_blank\" rel=\"noopener noreferrer\">TheTerminalist</a>'s blogpost: </div><a href=\"https://open.substack.com/pub/theterminalist/p/10000x-bloombergs-return-and-why\" target=\"_blank\" rel=\"noopener noreferrer\">10,000x. Bloomberg's return and why financial data is so darn lucrative</a><p></p><p></p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"the-openbb-approach-a-different-path\">The OpenBB approach: a different path<a href=\"https://didierlopes.com/blog/ui-layer-is-the-next-big-frontier#the-openbb-approach-a-different-path\" class=\"hash-link\" aria-label=\"Direct link to The OpenBB approach: a different path\" title=\"Direct link to The OpenBB approach: a different path\">​</a></h2>\n<p>We aren't competing with data vendors.</p>\n<p>Instead, we're offering something that no one else has attempted: a flexible, modular workspace where firms can build on top of their own data. Imagine a world where research is seamless, where AI is not just bolted on but deeply embedded into workflows, and where analysts spend more time uncovering insights rather than wrangling data.</p>\n<p>Data providers are starting to recognize this shift, but innovation on their platforms is slow.</p>\n<p>Meanwhile, AI is accelerating workflows at a pace that demands a new approach.</p>\n<p>AI chatbots alone aren't enough; without a stronger visualization and interaction layer, they remain a novelty rather than a necessity.</p>\n<p>With OpenBB, we are deliberately avoiding the data layer because we believe intelligence — the ability to derive value from data—is the future. Firms want more control over their data and the ability to leverage it without leakage.</p>\n<p>That's why the biggest demand we've seen is for on-prem deployments, ensuring security while unlocking intelligence.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"timing-matters-why-now\">Timing matters: why now?<a href=\"https://didierlopes.com/blog/ui-layer-is-the-next-big-frontier#timing-matters-why-now\" class=\"hash-link\" aria-label=\"Direct link to Timing matters: why now?\" title=\"Direct link to Timing matters: why now?\">​</a></h2>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-02-25-ui-layer-is-the-next-big-frontier_3.webp\"></p><p align=\"center\" class=\"mt-1\" style=\"font-size:0.75em\"></p><div>Excerpt from <a href=\"https://x.com/TheTerminalist\" target=\"_blank\" rel=\"noopener noreferrer\">TheTerminalist</a>'s blogpost: </div><a href=\"https://open.substack.com/pub/theterminalist/p/10000x-bloombergs-return-and-why\" target=\"_blank\" rel=\"noopener noreferrer\">10,000x. Bloomberg's return and why financial data is so darn lucrative</a><p></p><p></p>\n<p>The cost of compute has dropped, making powerful AI-driven applications more feasible.</p>\n<p>The best products emerge at the intersection of technical and domain expertise, and that's exactly where OpenBB sits—with deep engineering talent combined with financial knowledge.</p>\n<p>One of our clients recently put it best:</p>\n<blockquote>\n<p><em>\"OpenBB is the bridge infrastructure between my data and my intelligence.\"</em></p>\n</blockquote>\n<br>\n<p>That's the mission.</p>\n<p>Not just another financial tool, but a true workspace for the next generation of research and analytics.</p>\n<p>If you have your own data in Snowflake, Databricks, GCP, Azure or other, and want to build a customized workspace that fits your needs - reach out.</p>\n<p>The future of finance is being rewritten.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/ui-layer-is-the-next-big-frontier",
            "title": "UI layer is the next big frontier",
            "summary": "A deep dive into why the UI layer represents the next major frontier in financial technology. While the industry has heavily invested in data, the user interface remains a critical yet overlooked bridge between raw information and actionable intelligence. This piece explores how OpenBB is leading the charge in revolutionizing how financial professionals interact with data.",
            "date_modified": "2025-02-25T00:00:00.000Z",
            "tags": [
                "openbb",
                "fintech",
                "ui",
                "ux",
                "innovation",
                "financial-software",
                "data-visualization",
                "future-of-finance"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/long-live-long-context-with-gemini",
            "content_html": "<p align=\"center\"><img width=\"900\" src=\"https://didierlopes.com/blog/2025-02-18-long-live-long-context-with-gemini.webp\"></p>\n<p>A practical exploration of using Gemini's long context window capabilities to analyze multi-page documents, featuring a Streamlit app for testing and iterating prompts.</p>\n<p>Learn how to move beyond traditional RAG approaches for document analysis and leverage the power of large context windows for more accurate information retrieval.</p>\n<p>The open source code is available <a href=\"https://github.com/DidierRLopes/long-live-long-context\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<!-- -->\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"introduction\">Introduction<a href=\"https://didierlopes.com/blog/long-live-long-context-with-gemini#introduction\" class=\"hash-link\" aria-label=\"Direct link to Introduction\" title=\"Direct link to Introduction\">​</a></h2>\n<p>Last week, a friend of mine was mentioning an interesting challenge that they had. They had to handle multiple documents with over 200-300 pages each with text, tables and images. Their current process of doing this with RAG wasn't leading to the best results and it was very time consuming when analyzing the results. But also there wasn't a systematic approach being taken to improve the prompt for data retrieval (e.g. few-shot prompt).</p>\n<p>Given that I had been reading about people saying that \"RAG is dead\" because of Gemini models havign 1M+ input context, I wanted to test this model myself. At the same time I wanted to help my friend in setting up a pipeline that would help them automating their data retrieval pipeline.</p>\n<p>This post is going to focus on the approach I took, why and how you can set it up yourself.</p>\n<p>Note: This isn't meant to be a production ready pipeline, but enable you to \"vibe test\" your ingestion pipeline + data retrieval model + prompts. Funnily enough, this was mostly built in a day through <em>vibe coding</em> (Karpathy's coined the term recently).</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-02-18-long-live-long-context-with-gemini_1.webp\"></p><p align=\"center\" class=\"mt-1\" style=\"font-size:0.75em\"><a href=\"https://x.com/karpathy/status/1886192184808149383\" target=\"_blank\" rel=\"noopener noreferrer\">Karpathy tweet</a></p><p></p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"starting-point\">Starting point<a href=\"https://didierlopes.com/blog/long-live-long-context-with-gemini#starting-point\" class=\"hash-link\" aria-label=\"Direct link to Starting point\" title=\"Direct link to Starting point\">​</a></h2>\n<p>This is what my friend sent me:</p>\n<ul>\n<li>Complex PDFs with 200 pages comprised of text, images and tables</li>\n<li>An Excel spreadsheet with rows corresponding to values that were being attempted to retrieve and columns including prompt, value returned and correct value.</li>\n</ul>\n<p>The Excel spreadsheet effectively served as eval, which enabled them to understand whether a better model/pipeline would lead to better results or not. However, this process was very manual.</p>\n<p>The equivalent here is the following:</p>\n<ul>\n<li>\n<p>I will be using the following documents: <a href=\"https://github.com/DidierRLopes/long-live-long-context/blob/main/DeepSeek_R1.pdf\" target=\"_blank\" rel=\"noopener noreferrer\">DeepSeek_R1 paper</a> and <a href=\"https://github.com/DidierRLopes/long-live-long-context/blob/main/ME-cio-weekly-letter.pdf\" target=\"_blank\" rel=\"noopener noreferrer\">Capital Market Outlook report</a>. I just had these two at hand to serve as an example.</p>\n</li>\n<li>\n<p>I won't be using an Excel spreadsheet, but instead will rely on files in a directory called <code>data</code> within the project.</p>\n</li>\n</ul>\n<p>Here are the prompts that I'm going to test:</p>\n<table><thead><tr><th>idx</th><th>ID</th><th>Prompt</th><th>Expected Result</th></tr></thead><tbody><tr><td>0</td><td>Consumer Discretionary vs Consumer Staples comparison cap-weighted</td><td>By how much did Consumer Discretionary outperform Consumer Staples over the last three months on cap-weighted?</td><td>+17%</td></tr><tr><td>1</td><td>Consumer Discretionary vs Consumer Staples comparison equal-weighted</td><td>By how much did Consumer Discretionary outperform Consumer Staples over the last three months on equal-weighted?</td><td>+13%</td></tr><tr><td>2</td><td>Fed funds rate Q4 2024E</td><td>What is the Fed funds rate, end period (%) for Q4 2024E?</td><td>4.38</td></tr><tr><td>3</td><td>DeepSeek-R1-Zero GPQA Diamond pass@1</td><td>What was DeepSeek-R1-Zero GPQA Diamond pass@1 benchmark?</td><td>73.3</td></tr><tr><td>4</td><td>DeepSeek V3 C-SimpleQA</td><td>What was DeepSeek V3 C-SimpleQA bemchmark?</td><td>68.0%</td></tr><tr><td>5</td><td>Number of reasoning related training samples</td><td>How many reasoning related training samples were collected?</td><td>600k</td></tr></tbody></table>\n<p>Note: Prompts 0-2 can be found in Capital Market Outlook report whilst prompts 3-5 in DeepSeek R1 paper.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"setting-up-this-experiment\">Setting up this experiment<a href=\"https://didierlopes.com/blog/long-live-long-context-with-gemini#setting-up-this-experiment\" class=\"hash-link\" aria-label=\"Direct link to Setting up this experiment\" title=\"Direct link to Setting up this experiment\">​</a></h2>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"architecture\">Architecture<a href=\"https://didierlopes.com/blog/long-live-long-context-with-gemini#architecture\" class=\"hash-link\" aria-label=\"Direct link to Architecture\" title=\"Direct link to Architecture\">​</a></h3>\n<p>Create a folder called data with the following structure:</p>\n<div class=\"language-bash codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-bash codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">data/</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">├── system_prompt.txt</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">├── 0/</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">│   ├── id.txt</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">│   ├── prompt.txt</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">│   └── expected.txt</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">└── 1/</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    ├── id.txt</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    ├── prompt.txt</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    └── expected.txt</span><br></span></code></pre></div></div>\n<p>See our example <a href=\"https://github.com/DidierRLopes/long-live-long-context/tree/main/data\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<p>Let's go through each of these:</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"system-prompt\">System prompt<a href=\"https://didierlopes.com/blog/long-live-long-context-with-gemini#system-prompt\" class=\"hash-link\" aria-label=\"Direct link to System prompt\" title=\"Direct link to System prompt\">​</a></h3>\n<p>Contains the system prompt to be used throughout entire application in a <code>system_prompt.txt</code> file.</p>\n<p align=\"center\"><img width=\"1200\" src=\"https://didierlopes.com/blog/2025-02-18-long-live-long-context-with-gemini_2.webp\"></p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"prompt\">Prompt<a href=\"https://didierlopes.com/blog/long-live-long-context-with-gemini#prompt\" class=\"hash-link\" aria-label=\"Direct link to Prompt\" title=\"Direct link to Prompt\">​</a></h3>\n<p>Each prompt will have a folder with the idx in the order of it being run - e.g. 0, 1, 2, ...</p>\n<p>Inside this folder you will find 3 files: <code>id.txt</code>, <code>prompt.txt</code> and <code>expected.txt</code>. Note that this follows the table that we displayed above.</p>\n<h4 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"id\">ID<a href=\"https://didierlopes.com/blog/long-live-long-context-with-gemini#id\" class=\"hash-link\" aria-label=\"Direct link to ID\" title=\"Direct link to ID\">​</a></h4>\n<p>Contains an identifier that we can use to understand what prompt that is. This can be a slug of the prompt, a KPI number or anything else. It doesn't affect anything apart from helping user to be able to distinguish more easily between prompts at a higher level.</p>\n<p align=\"center\"><img width=\"1200\" src=\"https://didierlopes.com/blog/2025-02-18-long-live-long-context-with-gemini_3.webp\"></p>\n<h4 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"prompt-1\">Prompt<a href=\"https://didierlopes.com/blog/long-live-long-context-with-gemini#prompt-1\" class=\"hash-link\" aria-label=\"Direct link to Prompt\" title=\"Direct link to Prompt\">​</a></h4>\n<p>Contains the actual prompt to run through all the documents that have been loaded.</p>\n<p align=\"center\"><img width=\"1200\" src=\"https://didierlopes.com/blog/2025-02-18-long-live-long-context-with-gemini_4.webp\"></p>\n<h4 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"expected\">Expected<a href=\"https://didierlopes.com/blog/long-live-long-context-with-gemini#expected\" class=\"hash-link\" aria-label=\"Direct link to Expected\" title=\"Direct link to Expected\">​</a></h4>\n<p>Contains the expected value or information to be retrieved.</p>\n<p align=\"center\"><img width=\"1200\" src=\"https://didierlopes.com/blog/2025-02-18-long-live-long-context-with-gemini_5.webp\"></p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"running-the-streamlit-app\">Running the Streamlit app<a href=\"https://didierlopes.com/blog/long-live-long-context-with-gemini#running-the-streamlit-app\" class=\"hash-link\" aria-label=\"Direct link to Running the Streamlit app\" title=\"Direct link to Running the Streamlit app\">​</a></h2>\n<p>Clone <a href=\"https://github.com/DidierRLopes/long-live-long-context\" target=\"_blank\" rel=\"noopener noreferrer\">this repository</a>.</p>\n<p>Install the following libraries with <code>pip install &lt;library&gt;</code>:</p>\n<div class=\"language-bash codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-bash codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">streamlit</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">google-generativeai</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">PyMuPDF</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">pytesseract</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">pdf2image</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">Pillow</span><br></span></code></pre></div></div>\n<p>or simply do <code>pip install -r requirements.txt</code>.</p>\n<p>Retrieve a Gemini API key from <a href=\"https://ai.google.dev/gemini-api/docs/api-key\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<p>And finally run <code>streamlit run app.py</code>.</p>\n<p>Note: This application has 500 lines of code and all the logic lives in <a href=\"https://github.com/DidierRLopes/long-live-long-context/blob/main/app.py\" target=\"_blank\" rel=\"noopener noreferrer\">app.py</a>.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"how-the-app-works\">How the app works<a href=\"https://didierlopes.com/blog/long-live-long-context-with-gemini#how-the-app-works\" class=\"hash-link\" aria-label=\"Direct link to How the app works\" title=\"Direct link to How the app works\">​</a></h2>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"1-gemini-api-key\">1. Gemini API key<a href=\"https://didierlopes.com/blog/long-live-long-context-with-gemini#1-gemini-api-key\" class=\"hash-link\" aria-label=\"Direct link to 1. Gemini API key\" title=\"Direct link to 1. Gemini API key\">​</a></h3>\n<p>Since the purpose of this is to test Gemini 2.0 Flash model, then we are asking for the API key to be inserted at the top of the script. It could also have been done through <code>.env</code> variable which in general is a better alternative, but I wanted to make this more easier on the people who will run this script.</p>\n<p align=\"center\"><img width=\"1200\" src=\"https://didierlopes.com/blog/2025-02-18-long-live-long-context-with-gemini_6.webp\"></p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"2-system-prompt\">2. System Prompt<a href=\"https://didierlopes.com/blog/long-live-long-context-with-gemini#2-system-prompt\" class=\"hash-link\" aria-label=\"Direct link to 2. System Prompt\" title=\"Direct link to 2. System Prompt\">​</a></h3>\n<p>This is the system prompt that will be used across all prompts utilized to retrieve data from context.</p>\n<p align=\"center\"><img width=\"1200\" src=\"https://didierlopes.com/blog/2025-02-18-long-live-long-context-with-gemini_7.webp\"></p>\n<p>The EDIT button allows user to modify the content that lives in <a href=\"https://github.com/DidierRLopes/long-live-long-context/blob/main/data/system_prompt.txt\" target=\"_blank\" rel=\"noopener noreferrer\"><code>data/system_prompt.txt</code></a> and override it.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"3-load-documents\">3. Load documents<a href=\"https://didierlopes.com/blog/long-live-long-context-with-gemini#3-load-documents\" class=\"hash-link\" aria-label=\"Direct link to 3. Load documents\" title=\"Direct link to 3. Load documents\">​</a></h3>\n<p>This allows the user to pick any document that are next to the <code>app.py</code> file on the root of the project. You can select multiple documents and their content will be appended together.</p>\n<p align=\"center\"><img width=\"1200\" src=\"https://didierlopes.com/blog/2025-02-18-long-live-long-context-with-gemini_8.webp\"></p>\n<p>When a document is loaded, you will be able to understand how many tokens each document utilizes when being pushed into Gemini 2.0 flash - through <code>model.count_tokens()</code>. In addition, you will understand how many tokens are being utilized with the combination of all documents uploaded.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"4-run-prompts\">4. Run prompts<a href=\"https://didierlopes.com/blog/long-live-long-context-with-gemini#4-run-prompts\" class=\"hash-link\" aria-label=\"Direct link to 4. Run prompts\" title=\"Direct link to 4. Run prompts\">​</a></h3>\n<p>This one is slightly more complex, let's take it each section at a time.</p>\n<p align=\"center\"><img width=\"1200\" src=\"https://didierlopes.com/blog/2025-02-18-long-live-long-context-with-gemini_9.webp\"></p>\n<h4 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"run-all-prompts\">Run all prompts<a href=\"https://didierlopes.com/blog/long-live-long-context-with-gemini#run-all-prompts\" class=\"hash-link\" aria-label=\"Direct link to Run all prompts\" title=\"Direct link to Run all prompts\">​</a></h4>\n<p>By clicking on \"▶️▶️▶️ Run all prompts\", all prompts get run utilizing Gemini 2.0 Flash with the context provided, in the following format:</p>\n<div class=\"language-python codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-python codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">response </span><span class=\"token operator\">=</span><span class=\"token plain\"> model</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">generate_content</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">  </span><span class=\"token string-interpolation string\" style=\"color:rgb(255, 121, 198)\">f\"\"\"</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token string-interpolation string\" style=\"color:rgb(255, 121, 198)\">  </span><span class=\"token string-interpolation interpolation punctuation\" style=\"color:rgb(248, 248, 242)\">{</span><span class=\"token string-interpolation interpolation\">system_prompt</span><span class=\"token string-interpolation interpolation punctuation\" style=\"color:rgb(248, 248, 242)\">}</span><span class=\"token string-interpolation string\" style=\"color:rgb(255, 121, 198)\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token string-interpolation string\" style=\"color:rgb(255, 121, 198)\">  ---</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token string-interpolation string\" style=\"color:rgb(255, 121, 198)\">  </span><span class=\"token string-interpolation interpolation punctuation\" style=\"color:rgb(248, 248, 242)\">{</span><span class=\"token string-interpolation interpolation\">st</span><span class=\"token string-interpolation interpolation punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token string-interpolation interpolation\">session_state</span><span class=\"token string-interpolation interpolation punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token string-interpolation interpolation\">document_content</span><span class=\"token string-interpolation interpolation punctuation\" style=\"color:rgb(248, 248, 242)\">}</span><span class=\"token string-interpolation string\" style=\"color:rgb(255, 121, 198)\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token string-interpolation string\" style=\"color:rgb(255, 121, 198)\">  ---</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token string-interpolation string\" style=\"color:rgb(255, 121, 198)\">  </span><span class=\"token string-interpolation interpolation punctuation\" style=\"color:rgb(248, 248, 242)\">{</span><span class=\"token string-interpolation interpolation\">prompt</span><span class=\"token string-interpolation interpolation punctuation\" style=\"color:rgb(248, 248, 242)\">}</span><span class=\"token string-interpolation string\" style=\"color:rgb(255, 121, 198)\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token string-interpolation string\" style=\"color:rgb(255, 121, 198)\">  \"\"\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">  generation_config</span><span class=\"token operator\">=</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">{</span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"temperature\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"> </span><span class=\"token number\">0</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">}</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><br></span></code></pre></div></div>\n<p>The \"Free Gemini tier (adds timer if running all prompts)\" toggle is meant for users that aren't paying for Google API and adds a 60s delay after running each prompt. Note: Upgrading to a paid API key is recommended if you are dealing with sensitive data, so that your data is not used by Google for training.</p>\n<p>Remember: \"If something is free, you are the product\" 🙂.</p>\n<p>Now you may be wondering:</p>\n<blockquote>\n<p><em>\"Why is there a green '✅ Response matches expected result' box. How does the model know that the answer is accurate?\"</em>.</p>\n</blockquote>\n<br>\n<p>That is because after running the prompt, I take the output and use Gemini 2.0 Flash to compare it against the compared answer. Basically doing LLM as a judge so I have a quick sense of how many prompts I got correct and which ones I didn't and work on the failed ones.</p>\n<p>This is the prompt that happens under the hood:</p>\n<div class=\"language-python codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-python codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">comparison_response </span><span class=\"token operator\">=</span><span class=\"token plain\"> model</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">generate_content</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">  </span><span class=\"token string-interpolation string\" style=\"color:rgb(255, 121, 198)\">f\"\"\"</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token string-interpolation string\" style=\"color:rgb(255, 121, 198)\">  Compare these two texts and return only 'True' if they convey the same meaning,</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token string-interpolation string\" style=\"color:rgb(255, 121, 198)\">  or 'False' if they differ in meaning.</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token string-interpolation string\" style=\"color:rgb(255, 121, 198)\">  Don't worry about units as long as the numerical value are the same.</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token string-interpolation string\" style=\"display:inline-block;color:rgb(255, 121, 198)\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token string-interpolation string\" style=\"color:rgb(255, 121, 198)\">  Do not add anything else. Just one word: 'True' or 'False'.</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token string-interpolation string\" style=\"color:rgb(255, 121, 198)\">  </span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token string-interpolation string\" style=\"color:rgb(255, 121, 198)\">  Expected:</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token string-interpolation string\" style=\"color:rgb(255, 121, 198)\">  </span><span class=\"token string-interpolation interpolation punctuation\" style=\"color:rgb(248, 248, 242)\">{</span><span class=\"token string-interpolation interpolation\">expected</span><span class=\"token string-interpolation interpolation punctuation\" style=\"color:rgb(248, 248, 242)\">}</span><span class=\"token string-interpolation string\" style=\"color:rgb(255, 121, 198)\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token string-interpolation string\" style=\"color:rgb(255, 121, 198)\">  </span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token string-interpolation string\" style=\"color:rgb(255, 121, 198)\">  Actual:</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token string-interpolation string\" style=\"color:rgb(255, 121, 198)\">  </span><span class=\"token string-interpolation interpolation punctuation\" style=\"color:rgb(248, 248, 242)\">{</span><span class=\"token string-interpolation interpolation\">response</span><span class=\"token string-interpolation interpolation punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token string-interpolation interpolation\">text</span><span class=\"token string-interpolation interpolation punctuation\" style=\"color:rgb(248, 248, 242)\">}</span><span class=\"token string-interpolation string\" style=\"color:rgb(255, 121, 198)\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token string-interpolation string\" style=\"display:inline-block;color:rgb(255, 121, 198)\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token string-interpolation string\" style=\"color:rgb(255, 121, 198)\">  The meaning of the expected response and the actual response is the same. This statement is: </span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token string-interpolation string\" style=\"color:rgb(255, 121, 198)\">  \"\"\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">  generation_config</span><span class=\"token operator\">=</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">{</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">      </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"temperature\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"> </span><span class=\"token number\">0</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">      </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"candidate_count\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"> </span><span class=\"token number\">1</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">  </span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">}</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><br></span></code></pre></div></div>\n<h4 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"individual-prompts\">Individual prompts<a href=\"https://didierlopes.com/blog/long-live-long-context-with-gemini#individual-prompts\" class=\"hash-link\" aria-label=\"Direct link to Individual prompts\" title=\"Direct link to Individual prompts\">​</a></h4>\n<p>The concept of running an individual prompt is very similar to the run all prompts, with the exception that it takes approximately \"Run all prompts time\"/\"Number of all prompts\" for each. So it's better to iterate on a single prompt and the quality of its data retrieval.</p>\n<p>In addition, it has a few additional features that can be helpful to iterate:</p>\n<ul>\n<li>You can click on \"EDIT\" to edit the <code>prompt.txt</code> directly from the interface. This enables to tweak the prompt to be better at retrieving that specific information (e.g. few shot prompt, which is something that my friend wasn't doing and was contributing to lower accuracy).</li>\n<li>You can click on \"EDIT\" to edit the <code>expected.txt</code> directly from the interface. This was particularly relevant when I saw that the LLM as a judge failed when the model retrieved 68.0% for a particular prompt and the expected string I had was 68.0. In this case, the model was actually accurate and my expected value should have been either 68.0% or 0.68.</li>\n</ul>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"final-thoughts\">Final thoughts<a href=\"https://didierlopes.com/blog/long-live-long-context-with-gemini#final-thoughts\" class=\"hash-link\" aria-label=\"Direct link to Final thoughts\" title=\"Direct link to Final thoughts\">​</a></h2>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"data-ingestion\">Data ingestion<a href=\"https://didierlopes.com/blog/long-live-long-context-with-gemini#data-ingestion\" class=\"hash-link\" aria-label=\"Direct link to Data ingestion\" title=\"Direct link to Data ingestion\">​</a></h3>\n<p>This is one of the most important parts of the workflow:</p>\n<div class=\"language-python codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-python codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token comment\" style=\"color:rgb(98, 114, 164)\"># Convert PDF to images</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">images </span><span class=\"token operator\">=</span><span class=\"token plain\"> convert_from_path</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token plain\">tmp_path</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> dpi</span><span class=\"token operator\">=</span><span class=\"token number\">300</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token plain\">  </span><span class=\"token comment\" style=\"color:rgb(98, 114, 164)\"># can be increased for higher accuracy</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\"></span><span class=\"token comment\" style=\"color:rgb(98, 114, 164)\"># Open PDF with fitz</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">pdf_document </span><span class=\"token operator\">=</span><span class=\"token plain\"> fitz</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token builtin\" style=\"color:rgb(189, 147, 249)\">open</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token plain\">tmp_path</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">file_content </span><span class=\"token operator\">=</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"\"</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\"></span><span class=\"token comment\" style=\"color:rgb(98, 114, 164)\"># Process each page</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">for</span><span class=\"token plain\"> page_number </span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">in</span><span class=\"token plain\"> </span><span class=\"token builtin\" style=\"color:rgb(189, 147, 249)\">range</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token builtin\" style=\"color:rgb(189, 147, 249)\">len</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token plain\">pdf_document</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">  page </span><span class=\"token operator\">=</span><span class=\"token plain\"> pdf_document</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">load_page</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token plain\">page_number</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">  </span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">if</span><span class=\"token plain\"> page</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">get_drawings</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\">  </span><span class=\"token comment\" style=\"color:rgb(98, 114, 164)\"># OCR needed for vector content</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">      text </span><span class=\"token operator\">=</span><span class=\"token plain\"> pytesseract</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">image_to_string</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">          images</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">[</span><span class=\"token plain\">page_number</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">]</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> lang</span><span class=\"token operator\">=</span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"eng\"</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">      </span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">  </span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">else</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\">  </span><span class=\"token comment\" style=\"color:rgb(98, 114, 164)\"># Extract text directly</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">      text </span><span class=\"token operator\">=</span><span class=\"token plain\"> page</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">get_text</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"text\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">  file_content </span><span class=\"token operator\">+=</span><span class=\"token plain\"> text </span><span class=\"token operator\">+</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"\\n\"</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">pdf_document</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">close</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><br></span></code></pre></div></div>\n<p>From my friend results, I saw that it was consistently failing for a few prompts. The main reason for that was because the data was in a table that was an image underneat and the PDF reader didn't parse images. That meant that it didn't matter how good the prompt was, the model was set up for failure.</p>\n<p>I don't think the pipeline I've built is particularly strong but it highlights an example of how one can handle a scenario with text, tables and images going through each page individually by:</p>\n<ul>\n<li>Check if there is an image<!-- -->\n<ul>\n<li>If there is, do OCR using Tesseract to extract text</li>\n<li>If there isn't, use PyMuPDF to extract text</li>\n</ul>\n</li>\n</ul>\n<p>I believe that something that would improve results immediately is running the output of the OCR by a LLM and trying to reconstruct the table/image in markdown format if possible. I say this because I noticed that sometimes the OCR output can be a bit messy, and having an LLM focused on adding structure to each page OCR may lead to better outcomes.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"long-context-is-a-blessing\">Long context is a blessing<a href=\"https://didierlopes.com/blog/long-live-long-context-with-gemini#long-context-is-a-blessing\" class=\"hash-link\" aria-label=\"Direct link to Long context is a blessing\" title=\"Direct link to Long context is a blessing\">​</a></h3>\n<p>Something I noticed from the data my friend shared is that the RAG pipeline they had implemented struggled when the value that the model had to return wasn't immediate but it had to pick values from different places to piece it together.</p>\n<p>Imagine you were asking the model about the number of reasoning related training samples and the PDF mentioned that the number of reasoning related training samples was 2% of the training dataset samples. And in another page it said that the training dataset has 30 million samples. You need to get both of these in order to infer that the number of reasoning related training samples is 600k samples.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"subject-matter-experts-are-more-relevant-than-ever\">Subject matter experts are more relevant than ever<a href=\"https://didierlopes.com/blog/long-live-long-context-with-gemini#subject-matter-experts-are-more-relevant-than-ever\" class=\"hash-link\" aria-label=\"Direct link to Subject matter experts are more relevant than ever\" title=\"Direct link to Subject matter experts are more relevant than ever\">​</a></h3>\n<p>Despite advances in LLM capabilities, domain expertise remains crucial for effective prompt engineering. During testing, many retrieval failures stemmed not from model limitations, but from prompts that didn't properly account for domain-specific context and terminology.</p>\n<p>As a non-expert, I found it challenging to craft effective prompts because I lacked deep understanding of:</p>\n<ul>\n<li>How specific data points are typically represented in this type of document</li>\n<li>The precise meaning and significance of domain terminology</li>\n<li>Common document structures and conventions in the field</li>\n<li>How small variations in wording could make it so that the metric extracted wasn't the correct one</li>\n</ul>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"set-a-benchmark-and-work-reverse-from-there\">Set a benchmark and work reverse from there<a href=\"https://didierlopes.com/blog/long-live-long-context-with-gemini#set-a-benchmark-and-work-reverse-from-there\" class=\"hash-link\" aria-label=\"Direct link to Set a benchmark and work reverse from there\" title=\"Direct link to Set a benchmark and work reverse from there\">​</a></h3>\n<p>Before starting this work I had a benchmark where I was working backwards from. This was super helpful as it allows me to understand how this workflow, out-of-the-box, compares with my friends' one.</p>\n<p>Then we can work backwards from there and:</p>\n<ul>\n<li>Improve the system prompt</li>\n<li>Use a different model (and get rid of RAG eheh)</li>\n<li>Improve ingestion pipeline to process images</li>\n<li>Automate process a bit better with a Streamlit app</li>\n<li>Improve each individual prompt to retrieve information more accurately (few-shot prompt)</li>\n</ul>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"prompt-testing-and-validation\">Prompt testing and validation<a href=\"https://didierlopes.com/blog/long-live-long-context-with-gemini#prompt-testing-and-validation\" class=\"hash-link\" aria-label=\"Direct link to Prompt testing and validation\" title=\"Direct link to Prompt testing and validation\">​</a></h3>\n<p>Using LLMs as judges and being able to run prompts from the app, enabled to have a much more seamless workflow. This approach:</p>\n<ul>\n<li>Provides immediate feedback on prompt effectiveness</li>\n<li>Helps iterate and refine prompting strategies</li>\n<li>Ensures consistency in information extraction</li>\n<li>Reduces the need for manual verification</li>\n</ul>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"long-live-long-context\">Long live Long Context<a href=\"https://didierlopes.com/blog/long-live-long-context-with-gemini#long-live-long-context\" class=\"hash-link\" aria-label=\"Direct link to Long live Long Context\" title=\"Direct link to Long live Long Context\">​</a></h2>\n<p>Honestly, long context is f*ing awesome.</p>\n<p>Here are a few things that made me really happy:</p>\n<ul>\n<li>Ability to handle multiple documents at once without having to worry about chunking or managing context windows</li>\n<li>No need to worry about losing context between different sections of a document</li>\n<li>Reduced complexity in the overall pipeline since we don't need complex RAG infrastructure</li>\n<li>Better accuracy (in theory) since the model has access to the full context and can make connections across different parts of the document</li>\n<li>Faster development time since we don't need to spend time optimizing chunking strategies or fine-tuning retrieval mechanisms</li>\n</ul>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"next\">Next<a href=\"https://didierlopes.com/blog/long-live-long-context-with-gemini#next\" class=\"hash-link\" aria-label=\"Direct link to Next\" title=\"Direct link to Next\">​</a></h2>\n<p>I won't be spending more time on this project, as I did it to help a friend on their specific problem. I wrote this post so that I could share this with them and any other person in the future that is getting into LLMs.</p>\n<p>Feel free to fork the project and go wild.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/long-live-long-context-with-gemini",
            "title": "Long live long context with Gemini",
            "summary": "A practical exploration of using Gemini's long context window capabilities to analyze multi-page documents, featuring a Streamlit app for testing and iterating prompts.",
            "date_modified": "2025-02-18T00:00:00.000Z",
            "tags": [
                "ai",
                "llm",
                "gemini",
                "long-context",
                "rag",
                "streamlit",
                "python",
                "pdf-parsing",
                "prompt-engineering"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/what-it-means-to-have-skin-in-the-game",
            "content_html": "<p align=\"center\"><img width=\"900\" src=\"https://didierlopes.com/blog/2025-01-30-what-it-means-to-have-skin-in-the-game.webp\"></p>\n<p>From getting the OpenBB logo tattooed to honoring a promise of a Bali trip, this is a personal reflection on what it truly means to have \"skin in the game\". It's not about reckless commitment, but about standing fully behind your words and actions - a principle that's shaped both my personal life and my approach to building OpenBB.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>I just finished reading Nassim Taleb's \"Skin in the Game,\" and it hit home in a big way. (PS: you can find more books that I've read over the years <a href=\"https://didierlopes.com/books/already-read\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>).</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-01-30-what-it-means-to-have-skin-in-the-game_1.webp\"></p>\n<p>The idea of having real stakes in your decisions isn't new to me – it's something I've lived by for as long as I can remember. Taleb's writing puts it into words beautifully, but for me, this has always been a way of life.</p>\n<p>I believe in going all-in on what matters. In fact, I'm so committed to this philosophy that I have OpenBB logo tattooed on my body.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-01-30-what-it-means-to-have-skin-in-the-game.webp\"></p>\n<p>It's not about showing off or trying to prove something. It's a reminder that when I'm in, I'm all the way in. No half measures, no excuses. This isn't about taking wild risks for the sake of it – it's about standing behind what you believe in, fully and without hesitation.</p>\n<p>This mindset started when I was young, mostly from my dad.</p>\n<p>I learned that our word has to mean something. Promises weren't just things I would say, they were real commitments that I always followed through.</p>\n<p>I remember when we were kids I told one of my friends jokingly \"if you do x, I will give you 2 euros\" and he did it and we laughed. The day after I brought him 2 euros to school and he had forgotten about it.</p>\n<p>More recently, I promised my friends that if the open source project I had started (Gamestonk Terminal) ever became a company, I'd cover a two-week stay accommodation in Bali. When <a href=\"https://openbb.co/blog/gme-didnt-take-me-to-the-moon-but-gamestonk-terminal-did\" target=\"_blank\" rel=\"noopener noreferrer\">OpenBB raised money</a>, I let them know and we booked that trip for the following year.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-01-30-what-it-means-to-have-skin-in-the-game_2.webp\"></p>\n<p>That wasn't just talk. It was a real promise, tied to real accountability.</p>\n<p>The way I see it, taking risks and owning the results – good or bad – is what separates people who truly stand for something from those who just talk about it. When you're all in, you can't hide. If things go wrong, you take the hit. If they go right, you've earned it. Either way, you're accountable.</p>\n<p>This idea of skin in the game just makes so much sense to me, why wouldn't you?</p>\n<p>It's about showing up fully in everything you do, whether it's work, relationships, or personal goals. And it's about being honest with yourself and others when things don't go as planned.</p>\n<p>Trust is built by following through, especially when it's hard. When people know you'll keep your word, even when it's inconvenient, you build something way more valuable than a quick win: you build real trust. And that trust isn't just given; it's earned through consistency and integrity.</p>\n<p>These days, it feels like too many people are afraid to commit. They hedge their bets, avoid risks, and try to keep their options open. But I've found that being all-in – really having skin in the game – is the best way to live life.</p>\n<p>You can also see this by the fact that I am pretty much an open book - either sharing what I'm thinking through blogs like this or sharing all my code on GitHub.</p>\n<p>For the better, or the worst.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/what-it-means-to-have-skin-in-the-game",
            "title": "What it means to have skin in the game",
            "summary": "From getting the OpenBB logo tattooed to honoring a promise of a Bali trip, this is a personal reflection on what it truly means to have \"skin in the game\". It's not about reckless commitment, but about standing fully behind your words and actions - a principle that's shaped both my personal life and my approach to building OpenBB.",
            "date_modified": "2025-01-30T00:00:00.000Z",
            "tags": [
                "openbb",
                "leadership",
                "philosophy",
                "accountability",
                "commitment",
                "startup",
                "skin-in-the-game",
                "personal-story"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/building-a-developer-friendly-interface-for-financial-analysts",
            "content_html": "<p align=\"center\"><img width=\"900\" src=\"https://didierlopes.com/blog/2025-01-24-building-a-developer-friendly-interface-for-financial-analysts.webp\"></p>\n<p>It's an open, AI-native application that unifies data, streamlines workflows, and delivers enterprise-grade collaboration and control for teams of all sizes</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p><strong>What is the OpenBB Workspace, and how is it reimagining financial analysis?</strong></p>\n<p>Our workspace represents a paradigm shift in financial analysis - a unified platform that combines enterprise-grade power with an interface users love. We've created an ecosystem that doesn't just solve today's challenges in data integration and analysis - it anticipates tomorrow's needs.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"collaborative\">Collaborative<a href=\"https://didierlopes.com/blog/building-a-developer-friendly-interface-for-financial-analysts#collaborative\" class=\"hash-link\" aria-label=\"Direct link to Collaborative\" title=\"Direct link to Collaborative\">​</a></h3>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-01-24-building-a-developer-friendly-interface-for-financial-analysts_1.webp\"></p>\n<p>The OpenBB workspace combines three essential pillars that transform how teams work with financial data:</p>\n<ul>\n<li>\n<p><strong>Empowering analysts</strong>: Break free from technical constraints - analysts can create sophisticated workflows and dynamic dashboards with an intuitive interface, accelerating time-to-insight without writing a single line of code.</p>\n</li>\n<li>\n<p><strong>Unmatched security and control</strong>: Enterprise-grade security meets operational flexibility with on-premises deployment options, granular access controls, and complete audit trails that satisfy the most stringent compliance requirements.</p>\n</li>\n<li>\n<p><strong>Truly collaborative platform</strong>: Transform siloed analysis into synchronized teamwork with real-time collaboration features that enable instant sharing, live co-editing, and seamless knowledge transfer across teams.</p>\n</li>\n</ul>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"unified-data-integration\">Unified data integration<a href=\"https://didierlopes.com/blog/building-a-developer-friendly-interface-for-financial-analysts#unified-data-integration\" class=\"hash-link\" aria-label=\"Direct link to Unified data integration\" title=\"Direct link to Unified data integration\">​</a></h3>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-01-24-building-a-developer-friendly-interface-for-financial-analysts_2.webp\"></p>\n<p>Our open source data integration framework (<a href=\"https://github.com/OpenBB-finance/backend-for-terminal-pro\" target=\"_blank\" rel=\"noopener noreferrer\">open source repository here</a>) supports:</p>\n<ul>\n<li>\n<p><strong>Open ecosystem for developers</strong>: Drive innovation with our MIT-licensed framework - developers can rapidly build and deploy custom widgets that seamlessly integrate any data source, from proprietary feeds to public datasets.</p>\n</li>\n<li>\n<p><strong>Data agnostic</strong>: No data left behind - our platform effortlessly handles any financial data type, from traditional equities to crypto assets, adapting to your evolving analytical needs.</p>\n</li>\n<li>\n<p><strong>Built for scale</strong>: Enterprise-ready architecture that scales with your ambition - analyze thousands of datasets simultaneously, build complex dashboards, and leverage AI seamlessly.</p>\n</li>\n</ul>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"ai-powered-intelligence\">AI-powered intelligence<a href=\"https://didierlopes.com/blog/building-a-developer-friendly-interface-for-financial-analysts#ai-powered-intelligence\" class=\"hash-link\" aria-label=\"Direct link to AI-powered intelligence\" title=\"Direct link to AI-powered intelligence\">​</a></h3>\n<p>A single interface that transforms complex financial analysis into an intuitive, powerful experience.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-01-24-building-a-developer-friendly-interface-for-financial-analysts_3.webp\"></p>\n<p>Our open agentic framework (<a href=\"https://github.com/OpenBB-finance/copilot-for-openbb\" target=\"_blank\" rel=\"noopener noreferrer\">open source repository here</a>) delivers intelligent capabilities through three key pillars:</p>\n<ul>\n<li>\n<p><strong>Integrated  intelligence</strong>: Experience seamless AI augmentation that enhances rather than disrupts - AI agents work invisibly alongside your team, amplifying capabilities while maintaining absolute data privacy and security.</p>\n</li>\n<li>\n<p><strong>Tailored and secure</strong>: Purpose-built AI systems that understand the nuances of financial data - delivering precise, context-aware insights while maintaining security standards and complete control over your data.</p>\n</li>\n<li>\n<p><strong>Transparent and actionable</strong>: AI you can trust and verify - every insight comes with clear reasoning and sourcing, automatically integrated into your dashboards for immediate action and impact.</p>\n</li>\n</ul>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"unified-workspace\">Unified Workspace<a href=\"https://didierlopes.com/blog/building-a-developer-friendly-interface-for-financial-analysts#unified-workspace\" class=\"hash-link\" aria-label=\"Direct link to Unified Workspace\" title=\"Direct link to Unified Workspace\">​</a></h2>\n<p align=\"center\"><img width=\"900\" src=\"https://didierlopes.com/blog/2025-01-24-building-a-developer-friendly-interface-for-financial-analysts.webp\"></p>\n<p>We have organically grown our user base to nearly 80,000 through strategic partnerships and an unwavering commitment to user experience.</p>\n<p>We're not just building software – we're pioneering a future where financial tools are:</p>\n<ul>\n<li>Loved by users for their intuitive design and powerful capabilities</li>\n<li>Trusted by organizations for enterprise-grade security and control</li>\n<li>Designed for seamless, real-world collaboration at any scale</li>\n</ul>\n<p align=\"center\"><a href=\"https://www.producthunt.com/golden-kitty-awards/finance-tech-2\" target=\"_blank\"><img src=\"https://api.producthunt.com/widgets/embed-image/v1/featured.svg?post_id=491158&amp;theme=dark\" alt=\"OpenBB Terminal 2.0 - Open source investment research platform | Product Hunt\" style=\"width:250px;height:54px\"></a></p>\n<p>If you read this far, we'd appreciate your vote in the <a href=\"https://www.producthunt.com/golden-kitty-awards/finance-tech-2\" target=\"_blank\" rel=\"noopener noreferrer\">Finance Tech category of the Golden Kitty Awards on Product Hunt</a>.</p>\n<p>Thank you.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/building-a-developer-friendly-interface-for-financial-analysts",
            "title": "Building a developer friendly interface for financial analysts",
            "summary": "In the financial software industry, there's a well-worn playbook - build proprietary software, deploy large sales teams, and leverage executive relationships. At OpenBB, we're taking a fundamentally different approach - creating open-source financial tools that users genuinely love to use.",
            "date_modified": "2025-01-24T00:00:00.000Z",
            "tags": [
                "openbb",
                "plg",
                "pls",
                "open-source",
                "fintech",
                "ux",
                "sales",
                "startup"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/turn-my-blog-feed-into-a-qa-dataset-to-fine-tune-a-llm",
            "content_html": "<p align=\"center\"><img width=\"900\" src=\"https://didierlopes.com/blog/2025-01-21-turn-my-blog-feed-into-a-qa-dataset-to-fine-tune-a-llm.webp\"></p>\n<p>This project converts blog feed content into a structured Question-Answer dataset using LLaMA 3.2 (via Ollama) for local processing. The generated dataset follows a conversational format and can be automatically pushed to Hugging Face.</p>\n<p>The open source code is available <a href=\"https://github.com/DidierRLopes/turn-blog-feed-into-qa-dataset\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<!-- -->\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>I was looking to fine-tune an open source LLM with content that I have produced in the past to see how advanced such LLMs were and how close I could get a model running locally to \"output tokens\" the same way I would.</p>\n<p>According to Daniel Kahneman and his book <a href=\"https://www.amazon.com/Thinking-Fast-Slow-Daniel-Kahneman/dp/0374533555\" target=\"_blank\" rel=\"noopener noreferrer\">Thinking, Fast and Slow</a>, humans have two modes of thought:</p>\n<ul>\n<li><strong>System 1</strong>: Fast, instinctive and emotional. An example of this are my <a href=\"https://x.com/didier_lopes\" target=\"_blank\" rel=\"noopener noreferrer\">posts on X</a>.</li>\n</ul>\n<p>There are multiple libraries out there to scrape data from X. One that I used recently, and liked (without requiring an X API key) was <a href=\"https://github.com/elizaOS/twitter-scraper-finetune\" target=\"_blank\" rel=\"noopener noreferrer\">Twitter scraper finetune from ElizaOS</a>.</p>\n<ul>\n<li><strong>System 2</strong>: Slower, more deliberative and more logic. An example of this is my blog, where some of these posts take me several hours to write and need to sleep on the topic before pushing.</li>\n</ul>\n<p>For this, I didn't find any good out-of-the-box library that allowed me to convert my posts into a QA dataset to fine-tune a model.</p>\n<p>So this is what I ended up building.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"getting-started\">Getting Started<a href=\"https://didierlopes.com/blog/turn-my-blog-feed-into-a-qa-dataset-to-fine-tune-a-llm#getting-started\" class=\"hash-link\" aria-label=\"Direct link to Getting Started\" title=\"Direct link to Getting Started\">​</a></h2>\n<p>In order to do this you will need:</p>\n<ul>\n<li>Python 3.11</li>\n<li>Poetry (for python dependencies)</li>\n<li>Ollama (to run Llama 3.2)</li>\n<li>Hugging Face account (for dataset upload)</li>\n</ul>\n<p>and obviously your blog in a JSON feed like <a href=\"https://didierlopes.com/blog/feed.json\" target=\"_blank\" rel=\"noopener noreferrer\"></a><a href=\"https://didierlopes.com/blog/feed.json\" target=\"_blank\" rel=\"noopener noreferrer\">https://didierlopes.com/blog/feed.json</a>.</p>\n<h4 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"1-install-dependencies\">1. Install dependencies<a href=\"https://didierlopes.com/blog/turn-my-blog-feed-into-a-qa-dataset-to-fine-tune-a-llm#1-install-dependencies\" class=\"hash-link\" aria-label=\"Direct link to 1. Install dependencies\" title=\"Direct link to 1. Install dependencies\">​</a></h4>\n<div class=\"language-bash codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-bash codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">poetry install</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">poetry run python -m spacy download en_core_web_sm</span><br></span></code></pre></div></div>\n<h4 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"2-install-ollama-and-pull-llama-32\">2. Install Ollama and pull Llama 3.2<a href=\"https://didierlopes.com/blog/turn-my-blog-feed-into-a-qa-dataset-to-fine-tune-a-llm#2-install-ollama-and-pull-llama-32\" class=\"hash-link\" aria-label=\"Direct link to 2. Install Ollama and pull Llama 3.2\" title=\"Direct link to 2. Install Ollama and pull Llama 3.2\">​</a></h4>\n<p>Follow instructions to install Ollama: <a href=\"https://ollama.com/\" target=\"_blank\" rel=\"noopener noreferrer\">https://ollama.com/</a></p>\n<p>Select a model to run locally using <a href=\"https://ollama.com/search\" target=\"_blank\" rel=\"noopener noreferrer\">https://ollama.com/search</a>.</p>\n<p>In this case, we want to run <code>llama3.2:latest</code> (<a href=\"https://ollama.com/library/llama3.2\" target=\"_blank\" rel=\"noopener noreferrer\">https://ollama.com/library/llama3.2</a>).</p>\n<div class=\"language-bash codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-bash codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">ollama pull llama3.2:latest</span><br></span></code></pre></div></div>\n<p align=\"center\"><img width=\"900\" src=\"https://didierlopes.com/blog/2025-01-21-turn-my-blog-feed-into-a-qa-dataset-to-fine-tune-a-llm_1.webp\"></p>\n<p>Then, we can check that the model has been downloaded with:</p>\n<div class=\"language-bash codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-bash codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">ollama list</span><br></span></code></pre></div></div>\n<p align=\"center\"><img width=\"900\" src=\"https://didierlopes.com/blog/2025-01-21-turn-my-blog-feed-into-a-qa-dataset-to-fine-tune-a-llm_2.webp\"></p>\n<p>Finally, we can test that it works with:</p>\n<div class=\"language-bash codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-bash codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">ollama run llama3.2:latest</span><br></span></code></pre></div></div>\n<p align=\"center\"><img width=\"900\" src=\"https://didierlopes.com/blog/2025-01-21-turn-my-blog-feed-into-a-qa-dataset-to-fine-tune-a-llm_3.webp\"></p>\n<h4 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"3-configure-hugging-face\">3. Configure Hugging Face<a href=\"https://didierlopes.com/blog/turn-my-blog-feed-into-a-qa-dataset-to-fine-tune-a-llm#3-configure-hugging-face\" class=\"hash-link\" aria-label=\"Direct link to 3. Configure Hugging Face\" title=\"Direct link to 3. Configure Hugging Face\">​</a></h4>\n<ul>\n<li>\n<p>Create a write-enabled token at <a href=\"https://huggingface.co/docs/hub/en/security-tokens\" target=\"_blank\" rel=\"noopener noreferrer\">Hugging Face</a></p>\n</li>\n<li>\n<p>Create a <code>.env</code> file:</p>\n</li>\n</ul>\n<div class=\"language-bash codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-bash codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">HF_TOKEN=your_token_here</span><br></span></code></pre></div></div>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"usage\">Usage<a href=\"https://didierlopes.com/blog/turn-my-blog-feed-into-a-qa-dataset-to-fine-tune-a-llm#usage\" class=\"hash-link\" aria-label=\"Direct link to Usage\" title=\"Direct link to Usage\">​</a></h2>\n<p><strong>1. Update the blog feed URL in <a href=\"https://github.com/DidierRLopes/turn-blog-feed-into-qa-dataset/blob/main/turn-blog-feed-into-qa-dataset.ipynb\" target=\"_blank\" rel=\"noopener noreferrer\">this notebook</a>.</strong></p>\n<p>Below you can see the feed structure being used - which is the default coming from <a href=\"https://docusaurus.io/docs/blog\" target=\"_blank\" rel=\"noopener noreferrer\">Docusaurus</a>, which is the framework I'm using to auto-generate the feed for my personal blog.</p>\n<div class=\"language-python codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-python codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">url </span><span class=\"token operator\">=</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"https://didierlopes.com/blog/feed.json\"</span><br></span></code></pre></div></div>\n<details class=\"details_lb9f alert alert--info details_b_Ee\" data-collapsed=\"true\"><summary>JSON Feed Structure</summary><div><div class=\"collapsibleContent_i85q\"><div class=\"language-json codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-json codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">{</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\"></span><span class=\"token property\">\"version\"</span><span class=\"token operator\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"https://jsonfeed.org/version/1\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\"></span><span class=\"token property\">\"title\"</span><span class=\"token operator\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"Didier Lopes Blog\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> </span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\"></span><span class=\"token property\">\"home_page_url\"</span><span class=\"token operator\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"https://didierlopes.com/blog\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\"></span><span class=\"token property\">\"description\"</span><span class=\"token operator\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"Didier Lopes Blog\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\"></span><span class=\"token property\">\"items\"</span><span class=\"token operator\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">[</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">  </span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">{</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    </span><span class=\"token property\">\"id\"</span><span class=\"token operator\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"URL of the post\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    </span><span class=\"token property\">\"content_html\"</span><span class=\"token operator\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"HTML content of the post\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> </span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    </span><span class=\"token property\">\"url\"</span><span class=\"token operator\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"URL of the post\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    </span><span class=\"token property\">\"title\"</span><span class=\"token operator\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"Title of the post\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    </span><span class=\"token property\">\"summary\"</span><span class=\"token operator\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"Brief summary of the post\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    </span><span class=\"token property\">\"date_modified\"</span><span class=\"token operator\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"ISO 8601 date format\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    </span><span class=\"token property\">\"tags\"</span><span class=\"token operator\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">[</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">      </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"array\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">      </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"of\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> </span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">      </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"tags\"</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">]</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">  </span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">}</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">  </span><span class=\"token comment\" style=\"color:rgb(98, 114, 164)\">// ... more items</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">]</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">}</span><br></span></code></pre></div></div></div></div></details>\n<br>\n<p><strong>2. Set your Hugging Face dataset repository name:</strong></p>\n<div class=\"language-python codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-python codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">dataset_repo </span><span class=\"token operator\">=</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"didierlopes/my-blog-qa-dataset\"</span><br></span></code></pre></div></div>\n<p>This is what the dataset will look like in HuggingFace: <a href=\"https://huggingface.co/datasets/didierlopes/my-blog-qa-dataset/viewer\" target=\"_blank\" rel=\"noopener noreferrer\">https://huggingface.co/datasets/didierlopes/my-blog-qa-dataset/viewer</a>.</p>\n<p align=\"center\"><img width=\"900\" src=\"https://didierlopes.com/blog/2025-01-21-turn-my-blog-feed-into-a-qa-dataset-to-fine-tune-a-llm_4.webp\"></p>\n<br>\n<p><strong>3. Run the notebook cells sequentially.</strong></p>\n<p>The notebook contains detailed explanations throughout to guide you through the process step-by-step.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"dataset-format\">Dataset Format<a href=\"https://didierlopes.com/blog/turn-my-blog-feed-into-a-qa-dataset-to-fine-tune-a-llm#dataset-format\" class=\"hash-link\" aria-label=\"Direct link to Dataset Format\" title=\"Direct link to Dataset Format\">​</a></h2>\n<p>The generated dataset includes:</p>\n<ul>\n<li><code>title</code>: Blog post title</li>\n<li><code>conversation</code>: Array of Q&amp;A pairs in role-based format</li>\n<li><code>context</code>: Original cleaned blog content</li>\n<li><code>url</code>: Source blog post URL</li>\n<li><code>date</code>: Publication date</li>\n</ul>\n<p>Note: This is the format of the conversation field:</p>\n<div class=\"language-python codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-python codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">conversation </span><span class=\"token operator\">=</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">[</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">  </span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">{</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">      </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"role\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"user\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> </span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">      </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"content\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">          </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"You mentioned that when ChatGPT launched, everyone rushed to build \"</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">          </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"financial chatbots. What were some of the fundamental truths that \"</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">          </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"those who built these chatbots missed?\"</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">      </span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">  </span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">}</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">  </span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">{</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">      </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"role\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"assistant\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">      </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"content\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">          </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"Those building financial chatbots missed two fundamental truths:\"</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">          </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"1. AI models are useless without access to your data.\"</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">          </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"2. Access to data isn't enough - AI needs to handle complete \"</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">          </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"workflows, not just conversations.\"</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">          </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"These limitations led to chatbots that can't access proprietary \"</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">          </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"data, can't handle complex workflows and restrict analysts to an\"</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">          </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"unnatural chat interface.\"</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">      </span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">  </span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">}</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">  </span><span class=\"token comment\" style=\"color:rgb(98, 114, 164)\"># ... more Q&amp;A pairs following the same pattern</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">]</span><br></span></code></pre></div></div>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"summary-of-how-it-works\">Summary of how it works<a href=\"https://didierlopes.com/blog/turn-my-blog-feed-into-a-qa-dataset-to-fine-tune-a-llm#summary-of-how-it-works\" class=\"hash-link\" aria-label=\"Direct link to Summary of how it works\" title=\"Direct link to Summary of how it works\">​</a></h2>\n<ol>\n<li>Fetches blog content from JSON feed</li>\n<li>Cleans HTML to markdown format</li>\n<li>Analyzes sentence count to determine Q&amp;A pair quantity</li>\n<li>Generates contextual questions using LLaMA 3.2 running locally</li>\n<li>Creates corresponding answers</li>\n<li>Filters and removes duplicate Q&amp;A pairs</li>\n<li>Formats data for Hugging Face</li>\n<li>Pushes to Hugging Face Hub</li>\n</ol><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/turn-my-blog-feed-into-a-qa-dataset-to-fine-tune-a-llm",
            "title": "Turn my blog feed into a QA dataset to fine-tune a LLM",
            "summary": "This project converts blog feed content into a structured Question-Answer dataset using LLaMA 3.2 (via Ollama) for local processing. The generated dataset follows a conversational format and can be automatically pushed to Hugging Face.",
            "date_modified": "2025-01-21T00:00:00.000Z",
            "tags": [
                "ai",
                "ml",
                "llm",
                "dataset",
                "hugging-face",
                "ollama",
                "llama",
                "fine-tuning",
                "python"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/theres-a-zero-percent-chance-that-open-source-doesnt-win",
            "content_html": "<p align=\"center\"><img width=\"900\" src=\"https://didierlopes.com/blog/2025-01-16-theres-a-zero-percent-chance-that-open-source-doesnt-win.webp\"></p>\n<p>AI is transforming software development at a groundbreaking pace, creating a reinforcing cycle that makes open source unstoppable.</p>\n<p>As development costs plummet and AI tools make codebases more accessible than ever, the traditional moats of proprietary software are evaporating.</p>\n<p>Here's why I believe that the future of software is inevitably open.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>The pendulum of software development has swung between open and closed source for decades. While closed source has dominated many sectors due to massive capital investments by tech giants, we're approaching an inflection point where open source's victory seems not just possible, but unavoidable.</p>\n<p>The traditional moat of proprietary software companies – their secret sauce of complex codebases built over years with massive engineering teams – is rapidly eroding.</p>\n<p>AI tools are democratizing software development to an unprecedented degree (I recently wrote a small post about this <a href=\"https://didierlopes.com/blog/the-cost-of-building-software-is-plummeting-to-zero/\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>). A small team can now accomplish what previously required hundreds of engineers, dramatically reducing the cost and complexity of building sophisticated software systems.</p>\n<p>What's particularly interesting is how AI itself has been trained on vast repositories of open-source code. This creates a virtuous cycle: more open-source code leads to better AI models, which in turn simplifies contributions and enhances collaborative projects. The barriers to entry for meaningful code contributions have never been lower.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-01-16-theres-a-zero-percent-chance-that-open-source-doesnt-win.webp\"></p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"the-economic-equation-is-shifting\">The economic equation is shifting<a href=\"https://didierlopes.com/blog/theres-a-zero-percent-chance-that-open-source-doesnt-win#the-economic-equation-is-shifting\" class=\"hash-link\" aria-label=\"Direct link to The economic equation is shifting\" title=\"Direct link to The economic equation is shifting\">​</a></h2>\n<p>Historically, companies might have chosen closed-source solutions because the cost of customizing open-source alternatives was prohibitively high. You needed specialized engineers who understood the codebase intimately, and modifications often required significant time and resources. This equation is evolving swiftly.\nModern AI tools can:</p>\n<ul>\n<li>Analyze and explain complex codebases in seconds</li>\n<li>Suggest modifications and optimizations</li>\n<li>Generate custom implementations based on specific requirements</li>\n<li>Debug and troubleshoot issues perfectly</li>\n</ul>\n<p>This means companies can now take battle-tested open-source solutions and adapt them to their specific needs at a fraction of the traditional cost. The economic advantage of closed-source solutions is diminishing daily.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"the-network-effect-accelerates\">The network effect accelerates<a href=\"https://didierlopes.com/blog/theres-a-zero-percent-chance-that-open-source-doesnt-win#the-network-effect-accelerates\" class=\"hash-link\" aria-label=\"Direct link to The network effect accelerates\" title=\"Direct link to The network effect accelerates\">​</a></h2>\n<p>What makes this transformation particularly powerful is its self-reinforcing nature. Every company that chooses open source over proprietary solutions adds to the collective knowledge base. Each contribution, no matter how small, becomes part of the foundation that AI models learn from, making the next implementation easier and more robust.</p>\n<p>As AI tools get better at understanding and manipulating code, the advantages of open source multiply:</p>\n<ul>\n<li>Faster innovation cycles</li>\n<li>More diverse contributions from global developers</li>\n<li>Better security through transparent code review</li>\n<li>Reduced dependency on single vendors</li>\n<li>Lower total cost of ownership</li>\n</ul>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"the-path-forward\">The path forward<a href=\"https://didierlopes.com/blog/theres-a-zero-percent-chance-that-open-source-doesnt-win#the-path-forward\" class=\"hash-link\" aria-label=\"Direct link to The path forward\" title=\"Direct link to The path forward\">​</a></h2>\n<p>We're entering an era where the question isn't whether open source will win, but how long until it does.</p>\n<p>Companies that embrace this reality early will have a significant advantage. They'll benefit from:</p>\n<ul>\n<li>Reduced development costs<!-- -->\n<ul>\n<li>Larger pool of talent</li>\n<li>Benefit from AI models being trained on this data</li>\n</ul>\n</li>\n<li>Greater flexibility in customization</li>\n<li>Enhanced ability to attract talent who prefer working with open technologies</li>\n<li>Future-proofed technology stacks that can evolve with community innovations</li>\n</ul>\n<p>The momentum behind open source is becoming inescapable. As AI continues to lower the barriers to entry and make code more accessible, the advantages of closed-source systems will continue to erode. The future is open, and it's approaching faster than many realize.</p>\n<p>I mean, I can now literally run a 7b Mistral AI model on my machine, fine-tune it, and run it locally. From a technological perspective, this is the best time there ever was to build software.</p>\n<p>If you agree with this statement, why are you not building accordingly?</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/theres-a-zero-percent-chance-that-open-source-doesnt-win",
            "title": "There's a zero percent chance that open source doesn't win",
            "summary": "AI is democratizing software development at an unprecedented pace, and it's creating a virtuous cycle that makes open source unstoppable. As development costs plummet and AI tools make codebases more accessible than ever, the traditional moats of proprietary software are evaporating. Here's why I believe that the future of software is inevitably open.",
            "date_modified": "2025-01-16T00:00:00.000Z",
            "tags": [
                "open-source",
                "ai",
                "software-development",
                "future-of-tech",
                "democratization",
                "startup",
                "innovation"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/the-cost-of-building-software-is-plummeting-to-zero",
            "content_html": "<p align=\"center\"><img width=\"900\" src=\"https://didierlopes.com/blog/2025-01-09-the-cost-of-building-software-is-plummeting-to-zero.webp\"></p>\n<p>AI is revolutionizing software development costs and shifting value creation in the financial industry. I talk about the growing importance of data infrastructure, the rise of customizable solutions, and how OpenBB Workspace enables firms to build specialized AI-powered financial tools.</p>\n<p>The cost of building software is plummeting to zero—and it's happening faster than anyone predicted.</p>\n<p>AI isn't just transforming software development; it's completely rewriting the rules of the game. What once took months and millions now takes days and thousands.</p>\n<p>But here's the critical insight: this seismic shift is redistributing where value is created.</p>\n<p>Traditional desktop financial applications? They're becoming commodities. The real value is migrating rapidly to the data layer, the foundation beneath the application.</p>\n<p>Look at Snowflake's meteoric rise in financial services. It's not just adoption; it's a fundamental restructuring of how the industry manages and leverages data.</p>\n<p>So how do you build lasting value in this new landscape?</p>\n<p>The answer is threefold:</p>\n<ol>\n<li>Provide flexible, customizable infrastructure</li>\n<li>Embrace open-source and on-premise deployment</li>\n<li>Enable seamless integration of proprietary datasets</li>\n</ol>\n<br>\n<p>But 2025 brings an even more transformative opportunity: AI agents that can be built on top of these applications, creating hyper-specialized workflows that adapt to each user's needs.</p>\n<p>While we're still under wraps about some of our client work, here's a concrete example: During the holiday break, our Director of Engineering showcased the future of portfolio management.</p>\n<p>Using OpenBB Workspace, he built a sophisticated portfolio optimization system that:</p>\n<ul>\n<li>Integrates his proprietary (and sensitive) portfolio data</li>\n<li>Leverages a custom AI agent for risk analysis</li>\n<li>Automatically rebalances his portfolio based on complex criteria</li>\n</ul>\n<p>This isn't just a tool - it's a glimpse into how OpenBB Workspace can transform entire departments within investment firms.</p>\n<p>This 6-minute demo of OpenBB Workspace is one of the most compelling I've seen.</p>\n<div class=\"flex place-items-center justify-center items-center rounded-sm mx-auto\"><iframe src=\"https://www.youtube.com/embed/K80ayaZYyk4?si=IA9sNtq2figh1k5m\" width=\"800\" height=\"400\"></iframe></div>\n<br>\n<p>The future of financial software is here.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/the-cost-of-building-software-is-plummeting-to-zero",
            "title": "The cost of building software is plummeting to zero",
            "summary": "AI is revolutionizing software development costs and shifting value creation in the financial industry. I talk about the growing importance of data infrastructure, the rise of customizable solutions, and how OpenBB Workspace enables firms to build specialized AI-powered financial tools.",
            "date_modified": "2025-01-09T00:00:00.000Z",
            "tags": [
                "ai",
                "software-development",
                "fintech",
                "data-infrastructure",
                "open-source",
                "snowflake",
                "openbb",
                "portfolio-optimization",
                "future-of-software"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/tracking-my-writing-progress-through-an-open-source-blog-tracker-generator",
            "content_html": "<p align=\"center\"><img width=\"900\" src=\"https://didierlopes.com/blog/2025-01-07-tracking-my-writing-progress-through-an-open-source-blog-tracker-generator.webp\"></p>\n<p>Learn how I built an open-source tool that generates beautiful SVG visualizations of your blog post history, supporting both JSON and ATOM XML feeds. Perfect for keeping yourself accountable and monitoring your writing progress over time.</p>\n<p>The open source code is available <a href=\"https://github.com/DidierRLopes/blog-history-generator\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<!-- -->\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>As a developer, you measure your productivity based on the <del>amount</del> quality of code you produce.</p>\n<p>If we assume that the quality coming from an engineer remains constant (slightly improving) based on their current experience and continuously growing knowledge of the codebase, then we can assume that their productivity can be measured based on the amount of code they push into the codebase.</p>\n<p>As the founder of OpenBB, I don't have a lot of time to code (at least not as much as I used to).</p>\n<p>But I love programming, so I try to hop into Cursor at least once a day (every day). Sometimes I just don't have the bandwidth, but it's much easier to fall into that if you are not constantly reminding yourself that you haven't coded since x days ago.</p>\n<p>So, in order to keep myself accountable I bought a DeskHub which sits on my desk and I use to keep track of when I am shipping.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-01-07-tracking-my-writing-progress-through-an-open-source-blog-tracker-generator_1.webp\"></p>\n<p>I am less interested in the quality and quantity, but that every day I open Cursor and do one of the following:</p>\n<ul>\n<li>Fix a small bug or improve UI/UX on OpenBB (usually during the day)</li>\n<li>Add a new feature (usually during evening as more time is required)</li>\n<li>Write a new post on my website, like this one (evenings or weekend)</li>\n<li>Do a side project (weekend or holidays)</li>\n</ul>\n<p>While this has been working for a while, I realized that - for me - writing is as important as coding.</p>\n<p>It not only helps me communicate better as a leader, but also (and more importantly) think more clearly.</p>\n<p>But I didn't have a way to track that I have been practicing writing and putting myself out there.</p>\n<p>So, I built one.</p>\n<p>I built a program that generates an SVG visualization of your blog post history - as long as you get your blog post history in ATOM XML or JSON feed.</p>\n<p>And open source it <a href=\"https://github.com/DidierRLopes/blog-history-generator\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"blog-format\">Blog format<a href=\"https://didierlopes.com/blog/tracking-my-writing-progress-through-an-open-source-blog-tracker-generator#blog-format\" class=\"hash-link\" aria-label=\"Direct link to Blog format\" title=\"Direct link to Blog format\">​</a></h2>\n<div class=\"language-javascript codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockTitle_OeMC\">Common interface that all formats must conform to</div><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-javascript codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv codeBlockLinesWithNumbering_o6Pm\" style=\"counter-reset:line-count 0\"><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">interface</span><span class=\"token plain\"> </span><span class=\"token class-name\">Post</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">{</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\"></span><span class=\"token literal-property property\">id</span><span class=\"token operator\">:</span><span class=\"token plain\"> string</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">;</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\"></span><span class=\"token literal-property property\">title</span><span class=\"token operator\">:</span><span class=\"token plain\"> string</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">;</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\"></span><span class=\"token literal-property property\">url</span><span class=\"token operator\">:</span><span class=\"token plain\"> string</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">;</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\"></span><span class=\"token literal-property property\">content_html</span><span class=\"token operator\">:</span><span class=\"token plain\"> string</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">;</span><span class=\"token plain\">     </span><span class=\"token comment\" style=\"color:rgb(98, 114, 164)\">// Falls back to 'content' in some formats</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\"></span><span class=\"token literal-property property\">summary</span><span class=\"token operator\">:</span><span class=\"token plain\"> string</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">;</span><span class=\"token plain\">           </span><span class=\"token comment\" style=\"color:rgb(98, 114, 164)\">// Falls back to 'excerpt' in some formats</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\"></span><span class=\"token literal-property property\">date_modified</span><span class=\"token operator\">:</span><span class=\"token plain\"> string</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">;</span><span class=\"token plain\">  </span><span class=\"token comment\" style=\"color:rgb(98, 114, 164)\">// Falls back to date_published/date/updated/published</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\"></span><span class=\"token literal-property property\">tags</span><span class=\"token operator\">:</span><span class=\"token plain\"> string</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">[</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">]</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">;</span><span class=\"token plain\">                </span><span class=\"token comment\" style=\"color:rgb(98, 114, 164)\">// Defaults to [] if missing</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">}</span></span><br></span></code></pre></div></div>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"examples\">Examples<a href=\"https://didierlopes.com/blog/tracking-my-writing-progress-through-an-open-source-blog-tracker-generator#examples\" class=\"hash-link\" aria-label=\"Direct link to Examples\" title=\"Direct link to Examples\">​</a></h2>\n<div class=\"tabs-container tabList__CuJ\"><ul role=\"tablist\" aria-orientation=\"horizontal\" class=\"tabs\"><li role=\"tab\" tabindex=\"0\" aria-selected=\"true\" class=\"tabs__item tabItem_LNqP tabs__item--active\">JSON</li><li role=\"tab\" tabindex=\"-1\" aria-selected=\"false\" class=\"tabs__item tabItem_LNqP\">ATOM XML</li></ul><div class=\"margin-top--md\"><div role=\"tabpanel\" class=\"tabItem_Ymn6\"><p>Example: <a href=\"https://didierlopes.com/blog/feed.json\" target=\"_blank\" rel=\"noopener noreferrer\"></a><a href=\"https://didierlopes.com/blog/feed.json\" target=\"_blank\" rel=\"noopener noreferrer\">https://didierlopes.com/blog/feed.json</a></p><br><p align=\"center\"><img width=\"900\" src=\"https://didierlopes.com/blog/2025-01-07-tracking-my-writing-progress-through-an-open-source-blog-tracker-generator_2.webp\"></p></div><div role=\"tabpanel\" class=\"tabItem_Ymn6\" hidden=\"\"><p>Example: <a href=\"https://simonwillison.net/tags/datasette.atom\" target=\"_blank\" rel=\"noopener noreferrer\"></a><a href=\"https://simonwillison.net/tags/datasette.atom\" target=\"_blank\" rel=\"noopener noreferrer\">https://simonwillison.net/tags/datasette.atom</a></p><br><p align=\"center\"><img width=\"900\" src=\"https://didierlopes.com/blog/2025-01-07-tracking-my-writing-progress-through-an-open-source-blog-tracker-generator_3.webp\"></p></div></div></div>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"quick-setup\">Quick Setup<a href=\"https://didierlopes.com/blog/tracking-my-writing-progress-through-an-open-source-blog-tracker-generator#quick-setup\" class=\"hash-link\" aria-label=\"Direct link to Quick Setup\" title=\"Direct link to Quick Setup\">​</a></h2>\n<ol>\n<li>\n<p>Fork this <a href=\"https://github.com/DidierRLopes/blog-history-generator\" target=\"_blank\" rel=\"noopener noreferrer\">repository</a>.</p>\n</li>\n<li>\n<p>Give the repo the correct permissions.</p>\n<ol>\n<li>Click on Settings.</li>\n<li>Then go into Actions and click General.</li>\n<li>Scroll down and in Workflow permissions set \"Read and write permissions\".</li>\n</ol>\n</li>\n</ol>\n<br>\n<p align=\"center\"><img width=\"900\" src=\"https://didierlopes.com/blog/2025-01-07-tracking-my-writing-progress-through-an-open-source-blog-tracker-generator_4.webp\"></p>\n<ol start=\"3\">\n<li>Run the workflow.<!-- -->\n<ol>\n<li>Click on Actions.</li>\n<li>Click on \"Generate Blog History\" on the left side.</li>\n<li>On the right side click on \"Run workflow\".</li>\n<li>A blog feed URL will be required to run this (e.g. <a href=\"https://didierlopes.com/blog/feed.json\" target=\"_blank\" rel=\"noopener noreferrer\">https://didierlopes.com/blog/feed.json</a> or <a href=\"https://simonwillison.net/tags/datasette.atom\" target=\"_blank\" rel=\"noopener noreferrer\">https://simonwillison.net/tags/datasette.atom</a>).</li>\n<li>Click \"Run workflow\".</li>\n</ol>\n</li>\n</ol>\n<br>\n<p align=\"center\"><img width=\"900\" src=\"https://didierlopes.com/blog/2025-01-07-tracking-my-writing-progress-through-an-open-source-blog-tracker-generator_5.webp\"></p>\n<p>That's it.</p>\n<p>The SVG will be available here: <a href=\"https://github.com/DidierRLopes/blog-history-generator/blob/main/output/blog-history.svg\" target=\"_blank\" rel=\"noopener noreferrer\">./output/blog-history.svg</a>.</p>\n<p align=\"center\"><img width=\"900\" src=\"https://didierlopes.com/blog/2025-01-07-tracking-my-writing-progress-through-an-open-source-blog-tracker-generator_6.webp\"></p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"more-customization\">More customization<a href=\"https://didierlopes.com/blog/tracking-my-writing-progress-through-an-open-source-blog-tracker-generator#more-customization\" class=\"hash-link\" aria-label=\"Direct link to More customization\" title=\"Direct link to More customization\">​</a></h2>\n<p>If you want further customization, you need to:</p>\n<ol>\n<li>\n<p>Clone this repository.</p>\n</li>\n<li>\n<p>Install dependencies.</p>\n</li>\n</ol>\n<div class=\"language-text codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-text codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">npm install</span><br></span></code></pre></div></div>\n<ol start=\"3\">\n<li>Run script.</li>\n</ol>\n<div class=\"language-text codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-text codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">npm run generate</span><br></span></code></pre></div></div>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"interactive\">Interactive<a href=\"https://didierlopes.com/blog/tracking-my-writing-progress-through-an-open-source-blog-tracker-generator#interactive\" class=\"hash-link\" aria-label=\"Direct link to Interactive\" title=\"Direct link to Interactive\">​</a></h2>\n<p>If for some reason you want this widget to be interactive, you can check <a href=\"https://github.com/DidierRLopes/my-website/blob/main/src/components/BlogHistory.tsx\" target=\"_blank\" rel=\"noopener noreferrer\">this</a> which is the one I used to integrate into <a href=\"https://didierlopes.com/\">my homepage</a>.</p>\n<p align=\"center\"><img width=\"900\" src=\"https://didierlopes.com/blog/2025-01-07-tracking-my-writing-progress-through-an-open-source-blog-tracker-generator_7.webp\"></p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/tracking-my-writing-progress-through-an-open-source-blog-tracker-generator",
            "title": "Tracking my writing progress through an open source blog tracker generator",
            "summary": "Learn how I built an open-source tool that generates beautiful SVG visualizations of your blog post history, supporting both JSON and ATOM XML feeds. Perfect for keeping yourself accountable and monitoring your writing progress over time.",
            "date_modified": "2025-01-07T00:00:00.000Z",
            "tags": [
                "writing",
                "productivity",
                "open-source",
                "svg",
                "visualization",
                "blog",
                "tracking",
                "metrics"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/building-an-ai-agent-from-scratch-that-can-post-on-bluesky",
            "content_html": "<p align=\"center\"><img width=\"900\" src=\"https://didierlopes.com/blog/2025-01-04-building-an-ai-agent-from-scratch-that-can-post-on-bluesky.webp\"></p>\n<p>A practical guide to building an AI agent that processes Telegram messages through a local LLM, gathers context from various sources (OpenBB, Perplexity, Grok), and automatically posts content to Bluesky.</p>\n<p>The open source code is available <a href=\"https://github.com/DidierRLopes/telegram-text-to-bluesky-post\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<!-- -->\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>Over the Christmas break, I decided to explore the world of fine-tuning while assessing the quality of open-source models that can run locally. This exploration is particularly important for me, as we frequently discuss with prospects the possibility of integrating local AI agents into OpenBB to avoid reliance on third-party vendors.</p>\n<p>To make this experiment practical and engaging, I needed a well-defined use case. My objective was straightforward: to develop an agent capable of focusing on a specific topic, gathering external information, and crafting a post to share on Bluesky triggered by myself.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2025-01-04-building-an-ai-agent-from-scratch-that-can-post-on-bluesky_1.webp\"></p>\n<p>This is the workflow we are looking at:</p>\n<ol>\n<li>I send a message to my Telegram bot with the idea of what I want to post on Bluesky.</li>\n<li>That message gets processed by my fine-tune agent, which runs locally.</li>\n<li>That message is used to extract further context either from:<!-- -->\n<ol>\n<li>OpenBB if financial information is needed.</li>\n<li>xAI if latest news from social media is needed.</li>\n<li>Perplexity if more information from the web is necessary.</li>\n</ol>\n</li>\n<li>The agent then writes a thought on the topic.</li>\n<li>Then it pushes that post to Bluesky.</li>\n</ol>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"getting-started\">Getting Started<a href=\"https://didierlopes.com/blog/building-an-ai-agent-from-scratch-that-can-post-on-bluesky#getting-started\" class=\"hash-link\" aria-label=\"Direct link to Getting Started\" title=\"Direct link to Getting Started\">​</a></h2>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"environment-setup\">Environment Setup<a href=\"https://didierlopes.com/blog/building-an-ai-agent-from-scratch-that-can-post-on-bluesky#environment-setup\" class=\"hash-link\" aria-label=\"Direct link to Environment Setup\" title=\"Direct link to Environment Setup\">​</a></h3>\n<p>You have a Bluesky account - like mine here: &nbsp;<a href=\"https://bsky.app/profile/didierlopes.com\" target=\"_blank\" rel=\"noopener noreferrer\">https://bsky.app/profile/didierlopes.com</a>.</p>\n<ul>\n<li>You will need <code>BLUESKY_HANDLE</code> and <code>BLUESKY_PASSWORD</code>.</li>\n</ul>\n<p>You have a Telegram account and you have created a bot by following the steps highlighted here: &nbsp;<a href=\"https://www.siteguarding.com/en/how-to-get-telegram-bot-api-token\" target=\"_blank\" rel=\"noopener noreferrer\">https://www.siteguarding.com/en/how-to-get-telegram-bot-api-token</a>.</p>\n<ul>\n<li>You will need <code>TELEGRAM_BOT_TOKEN</code>.</li>\n</ul>\n<p>You have installed Ollama and are running a model like <code>Llama3.2:latest</code> locally.</p>\n<p>Additionally, you will need the following tokens for the agent's tools:</p>\n<ul>\n<li><code>OPENBB_PAT</code> which you can retrieve from: <a href=\"https://my.openbb.co/app/platform/pat\" target=\"_blank\" rel=\"noopener noreferrer\">https://my.openbb.co/app/platform/pat</a></li>\n<li><code>PERPLEXITY_API_KEY</code> which you can retrieve from: <a href=\"https://www.perplexity.ai/settings/api\" target=\"_blank\" rel=\"noopener noreferrer\">https://www.perplexity.ai/settings/api</a></li>\n<li><code>GROK_API_KEY</code> which you can retrieve from: <a href=\"https://console.x.ai/\" target=\"_blank\" rel=\"noopener noreferrer\">https://console.x.ai/</a></li>\n</ul>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"main-libraries\">Main libraries<a href=\"https://didierlopes.com/blog/building-an-ai-agent-from-scratch-that-can-post-on-bluesky#main-libraries\" class=\"hash-link\" aria-label=\"Direct link to Main libraries\" title=\"Direct link to Main libraries\">​</a></h3>\n<p>The bot is built using several key libraries:</p>\n<ul>\n<li><strong>ATProto Client</strong>: For interacting with the Bluesky social network</li>\n<li><strong>Python-Telegram-Bot</strong>: For handling Telegram interactions</li>\n<li><strong>Asyncio</strong>: For handling asynchronous operations</li>\n<li><strong>OpenBB</strong>: To access financial data</li>\n<li><strong>OpenAI</strong>: to hit Perplexity and Grok OpenAI compatible endpoints</li>\n</ul>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"implementation\">Implementation<a href=\"https://didierlopes.com/blog/building-an-ai-agent-from-scratch-that-can-post-on-bluesky#implementation\" class=\"hash-link\" aria-label=\"Direct link to Implementation\" title=\"Direct link to Implementation\">​</a></h2>\n<p>For this tutorial, I'm not going to write about fine-tuning my own LLM to keep it simpler. I will leave that for another post where I want to share more on what I learned about doing so.</p>\n<p>I'm also going through the step-by-step I performed in order to complete this project, so that this can serve as an inspiration for somebody starting something.</p>\n<p>I have a folder called \"experiments\" <a href=\"https://github.com/DidierRLopes/telegram-text-to-bluesky-post/tree/main/experiments\" target=\"_blank\" rel=\"noopener noreferrer\">here</a> which I use to show you how I experiment each subsystem independently and only after each individually works I merge them together. Dividing and conquering here is fundamental.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"1-bluesky-api\">1. Bluesky API<a href=\"https://didierlopes.com/blog/building-an-ai-agent-from-scratch-that-can-post-on-bluesky#1-bluesky-api\" class=\"hash-link\" aria-label=\"Direct link to 1. Bluesky API\" title=\"Direct link to 1. Bluesky API\">​</a></h3>\n<p>I can't push a post to Bluesky if the API doesn't allow me to do so. Therefore, this is where I started.</p>\n<div class=\"language-python codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockTitle_OeMC\"><a href=\"https://github.com/DidierRLopes/telegram-text-to-bluesky-post/blob/main/experiments/bluesky-api.ipynb\" target=\"_blank\" rel=\"noopener noreferrer\" style=\"font-weight:bold;color:#0366d6\">/experiments/bluesky-api.ipynb</a></div><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-python codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv codeBlockLinesWithNumbering_o6Pm\" style=\"counter-reset:line-count 0\"><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">from</span><span class=\"token plain\"> atproto </span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">import</span><span class=\"token plain\"> Client</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> client_utils</span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">import</span><span class=\"token plain\"> os</span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">from</span><span class=\"token plain\"> dotenv </span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">import</span><span class=\"token plain\"> load_dotenv</span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\" style=\"display:inline-block\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">load_dotenv</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\" style=\"display:inline-block\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">client </span><span class=\"token operator\">=</span><span class=\"token plain\"> Client</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">profile </span><span class=\"token operator\">=</span><span class=\"token plain\"> client</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">login</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">  os</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">getenv</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">'BLUESKY_HANDLE'</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">  os</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">getenv</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">'BLUESKY_PASSWORD'</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">print</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">'Welcome,'</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> profile</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">display_name</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\" style=\"display:inline-block\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">text </span><span class=\"token operator\">=</span><span class=\"token plain\"> client_utils</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">TextBuilder</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">text</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">'Merry Christmas!'</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">post </span><span class=\"token operator\">=</span><span class=\"token plain\"> client</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">send_post</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token plain\">text</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">client</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">like</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token plain\">post</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">uri</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> post</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">cid</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span></span><br></span></code></pre></div></div>\n<p>The code is extremely simple, this made me understand how easy Bluesky API is to interact with.</p>\n<p>The only thing I added to this was to create a thread of posts if the 300 character post limit was crossed. I didn't know the limit was 300 characters, and so had to handle that situation after when merging all the pieces together since, it turns out, AI agents like to write long posts (or my prompt didn't hint at not doing so strong enough).</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"2-telegram-api\">2. Telegram API<a href=\"https://didierlopes.com/blog/building-an-ai-agent-from-scratch-that-can-post-on-bluesky#2-telegram-api\" class=\"hash-link\" aria-label=\"Direct link to 2. Telegram API\" title=\"Direct link to 2. Telegram API\">​</a></h3>\n<p>In order to push a post to Bluesky, I need to have something that triggers it.</p>\n<p>I could have automated this process as in \"at 9am every day post something on a topic\", but I wanted the subject to vary and retain control over what my agent does research on.</p>\n<p>Therefore, I chose Telegram to act as the \"trigger\". I have used Discord and Slack in the past, this allowed me to get familiar with interacting with a bot on Telegram.</p>\n<p>I was actually mind-blown by how simple they made the process. More on this here: <a href=\"https://www.siteguarding.com/en/how-to-get-telegram-bot-api-token\" target=\"_blank\" rel=\"noopener noreferrer\">https://www.siteguarding.com/en/how-to-get-telegram-bot-api-token</a>.</p>\n<p>Then I tested that I could send a Telegram bot a message that I would receive on the terminal where this code was running.</p>\n<details class=\"details_lb9f alert alert--info details_b_Ee\" data-collapsed=\"true\"><summary>View Telegram API Code</summary><div><div class=\"collapsibleContent_i85q\"><div class=\"language-python codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockTitle_OeMC\"><a href=\"https://github.com/DidierRLopes/telegram-text-to-bluesky-post/blob/main/experiments/telegram-api.py\" target=\"_blank\" rel=\"noopener noreferrer\" style=\"font-weight:bold;color:#0366d6\">/experiments/telegram-api.py</a></div><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-python codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv codeBlockLinesWithNumbering_o6Pm\" style=\"counter-reset:line-count 0\"><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">import</span><span class=\"token plain\"> logging</span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">from</span><span class=\"token plain\"> telegram </span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">import</span><span class=\"token plain\"> Update</span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">from</span><span class=\"token plain\"> telegram</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">ext </span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">import</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">  Application</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">  CommandHandler</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">  MessageHandler</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">  filters</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">  ContextTypes</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">import</span><span class=\"token plain\"> os</span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">from</span><span class=\"token plain\"> dotenv </span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">import</span><span class=\"token plain\"> load_dotenv</span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">import</span><span class=\"token plain\"> argparse</span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\" style=\"display:inline-block\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\"></span><span class=\"token comment\" style=\"color:rgb(98, 114, 164)\"># Load token from .env file</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">load_dotenv</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">TOKEN </span><span class=\"token operator\">=</span><span class=\"token plain\"> os</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">getenv</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"TELEGRAM_BOT_TOKEN\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\" style=\"display:inline-block\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">if</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">not</span><span class=\"token plain\"> TOKEN</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">  </span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">raise</span><span class=\"token plain\"> ValueError</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"No TOKEN found in .env file\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\" style=\"display:inline-block\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\"></span><span class=\"token comment\" style=\"color:rgb(98, 114, 164)\"># Initialize logger</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">logger </span><span class=\"token operator\">=</span><span class=\"token plain\"> logging</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">getLogger</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token plain\">__name__</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\" style=\"display:inline-block\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\" style=\"display:inline-block\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\"></span><span class=\"token comment\" style=\"color:rgb(98, 114, 164)\"># Move logging setup into a function</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">def</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(80, 250, 123)\">setup_logging</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token plain\">verbose</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"> </span><span class=\"token builtin\" style=\"color:rgb(189, 147, 249)\">bool</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token plain\"> </span><span class=\"token operator\">-</span><span class=\"token operator\">&gt;</span><span class=\"token plain\"> </span><span class=\"token boolean\">None</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">  level </span><span class=\"token operator\">=</span><span class=\"token plain\"> logging</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">INFO </span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">if</span><span class=\"token plain\"> verbose </span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">else</span><span class=\"token plain\"> logging</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">WARNING</span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">  logging</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">basicConfig</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">      </span><span class=\"token builtin\" style=\"color:rgb(189, 147, 249)\">format</span><span class=\"token operator\">=</span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"%(asctime)s - %(name)s - %(levelname)s - %(message)s\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> level</span><span class=\"token operator\">=</span><span class=\"token plain\">level</span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">  </span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\" style=\"display:inline-block\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\" style=\"display:inline-block\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">async</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">def</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(80, 250, 123)\">start</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token plain\">update</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"> Update</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> _context</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"> ContextTypes</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">DEFAULT_TYPE</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token plain\"> </span><span class=\"token operator\">-</span><span class=\"token operator\">&gt;</span><span class=\"token plain\"> </span><span class=\"token boolean\">None</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">  </span><span class=\"token triple-quoted-string string\" style=\"color:rgb(255, 121, 198)\">\"\"\"Send a message when the command /start is issued.\"\"\"</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">  user </span><span class=\"token operator\">=</span><span class=\"token plain\"> update</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">effective_user</span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">  </span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">await</span><span class=\"token plain\"> update</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">message</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">reply_html</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">      </span><span class=\"token string-interpolation string\" style=\"color:rgb(255, 121, 198)\">f\"Hi </span><span class=\"token string-interpolation interpolation punctuation\" style=\"color:rgb(248, 248, 242)\">{</span><span class=\"token string-interpolation interpolation\">user</span><span class=\"token string-interpolation interpolation punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token string-interpolation interpolation\">mention_html</span><span class=\"token string-interpolation interpolation punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token string-interpolation interpolation punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token string-interpolation interpolation punctuation\" style=\"color:rgb(248, 248, 242)\">}</span><span class=\"token string-interpolation string\" style=\"color:rgb(255, 121, 198)\">! \"</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">      </span><span class=\"token string-interpolation string\" style=\"color:rgb(255, 121, 198)\">f\"I'm a bot. Send me a message and I'll print it on the console.\"</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">  </span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\" style=\"display:inline-block\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\" style=\"display:inline-block\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">async</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">def</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(80, 250, 123)\">handle_message</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token plain\">update</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"> Update</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> _context</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"> ContextTypes</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">DEFAULT_TYPE</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token plain\"> </span><span class=\"token operator\">-</span><span class=\"token operator\">&gt;</span><span class=\"token plain\"> </span><span class=\"token boolean\">None</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">  </span><span class=\"token triple-quoted-string string\" style=\"color:rgb(255, 121, 198)\">\"\"\"Print the user message on the console.\"\"\"</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">  message </span><span class=\"token operator\">=</span><span class=\"token plain\"> update</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">message</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">text</span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">  user </span><span class=\"token operator\">=</span><span class=\"token plain\"> update</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">effective_user</span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">  chat_id </span><span class=\"token operator\">=</span><span class=\"token plain\"> update</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">effective_chat</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token builtin\" style=\"color:rgb(189, 147, 249)\">id</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\" style=\"display:inline-block\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">  logger</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">info</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">      </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"New message received from @%s (chat_id: %s): %s\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">      user</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">username</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">      chat_id</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">      message</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">  </span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\" style=\"display:inline-block\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">  </span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">print</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token string-interpolation string\" style=\"color:rgb(255, 121, 198)\">f\"Message from @</span><span class=\"token string-interpolation interpolation punctuation\" style=\"color:rgb(248, 248, 242)\">{</span><span class=\"token string-interpolation interpolation\">user</span><span class=\"token string-interpolation interpolation punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token string-interpolation interpolation\">username</span><span class=\"token string-interpolation interpolation punctuation\" style=\"color:rgb(248, 248, 242)\">}</span><span class=\"token string-interpolation string\" style=\"color:rgb(255, 121, 198)\">: </span><span class=\"token string-interpolation interpolation punctuation\" style=\"color:rgb(248, 248, 242)\">{</span><span class=\"token string-interpolation interpolation\">message</span><span class=\"token string-interpolation interpolation punctuation\" style=\"color:rgb(248, 248, 242)\">}</span><span class=\"token string-interpolation string\" style=\"color:rgb(255, 121, 198)\">\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\" style=\"display:inline-block\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\" style=\"display:inline-block\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">async</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">def</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(80, 250, 123)\">error_handler</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token plain\">_update</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"> </span><span class=\"token builtin\" style=\"color:rgb(189, 147, 249)\">object</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> context</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"> ContextTypes</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">DEFAULT_TYPE</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token plain\"> </span><span class=\"token operator\">-</span><span class=\"token operator\">&gt;</span><span class=\"token plain\"> </span><span class=\"token boolean\">None</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">  </span><span class=\"token triple-quoted-string string\" style=\"color:rgb(255, 121, 198)\">\"\"\"Log errors caused by Updates.\"\"\"</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">  logger</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">error</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"Exception while handling an update:\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> exc_info</span><span class=\"token operator\">=</span><span class=\"token plain\">context</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">error</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\" style=\"display:inline-block\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\" style=\"display:inline-block\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">def</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(80, 250, 123)\">main</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token plain\"> </span><span class=\"token operator\">-</span><span class=\"token operator\">&gt;</span><span class=\"token plain\"> </span><span class=\"token boolean\">None</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">  </span><span class=\"token comment\" style=\"color:rgb(98, 114, 164)\"># Add argument parsing</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">  parser </span><span class=\"token operator\">=</span><span class=\"token plain\"> argparse</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">ArgumentParser</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">  parser</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">add_argument</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"--verbose\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> action</span><span class=\"token operator\">=</span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"store_true\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> </span><span class=\"token builtin\" style=\"color:rgb(189, 147, 249)\">help</span><span class=\"token operator\">=</span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"Enable verbose logging\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">  args </span><span class=\"token operator\">=</span><span class=\"token plain\"> parser</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">parse_args</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\" style=\"display:inline-block\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">  </span><span class=\"token comment\" style=\"color:rgb(98, 114, 164)\"># Setup logging based on verbose flag</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">  setup_logging</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token plain\">args</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">verbose</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\" style=\"display:inline-block\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">  logger</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">info</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"Bot started. Waiting for messages...\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\" style=\"display:inline-block\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">  </span><span class=\"token comment\" style=\"color:rgb(98, 114, 164)\"># Create application</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">  app </span><span class=\"token operator\">=</span><span class=\"token plain\"> Application</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">builder</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">token</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token plain\">TOKEN</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">build</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\" style=\"display:inline-block\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">  </span><span class=\"token comment\" style=\"color:rgb(98, 114, 164)\"># Add handlers</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">  app</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">add_handler</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token plain\">CommandHandler</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"start\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> start</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">  app</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">add_handler</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token plain\">MessageHandler</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token plain\">filters</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">TEXT </span><span class=\"token operator\">&amp;</span><span class=\"token plain\"> </span><span class=\"token operator\">~</span><span class=\"token plain\">filters</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">COMMAND</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> handle_message</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\" style=\"display:inline-block\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">  </span><span class=\"token comment\" style=\"color:rgb(98, 114, 164)\"># Register error handler</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">  app</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">add_error_handler</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token plain\">error_handler</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\" style=\"display:inline-block\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">  </span><span class=\"token comment\" style=\"color:rgb(98, 114, 164)\"># Start polling</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">  app</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">run_polling</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token plain\">poll_interval</span><span class=\"token operator\">=</span><span class=\"token number\">1.0</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\" style=\"display:inline-block\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\" style=\"display:inline-block\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">if</span><span class=\"token plain\"> __name__ </span><span class=\"token operator\">==</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"__main__\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">  main</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span></span><br></span></code></pre></div></div></div></div></details>\n<p>The only additional things I added afterwards for a better user experience were:</p>\n<ul>\n<li>Shows processing status in text</li>\n<li>Provides the Bluesky post URL when complete</li>\n<li>Indicates if the post was threaded</li>\n<li>Reports any errors</li>\n</ul>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"3-agent-brain\">3. Agent brain<a href=\"https://didierlopes.com/blog/building-an-ai-agent-from-scratch-that-can-post-on-bluesky#3-agent-brain\" class=\"hash-link\" aria-label=\"Direct link to 3. Agent brain\" title=\"Direct link to 3. Agent brain\">​</a></h3>\n<p>I have used Ollama and <code>Llama3.2:latest</code> previously, and knew how easy it was to call the model. So I didn't bother spending time testing it up in advance.</p>\n<div class=\"language-python codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-python codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">response </span><span class=\"token operator\">=</span><span class=\"token plain\"> requests</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">post</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\"></span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"http://localhost:11434/api/generate\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">json</span><span class=\"token operator\">=</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">{</span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"model\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"> model</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"prompt\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"> post_prompt</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"stream\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"> </span><span class=\"token boolean\">False</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">}</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><br></span></code></pre></div></div>\n<p>However, I wanted to give some form of flexibility in case someone found some interest in the project - so they could bring their own custom models.</p>\n<p>So I put this code into a folder called <code>agents</code> and each file here has a class <code>LanguageModelWrapper</code>and works as an agent with (potential) access to tools.</p>\n<p>The code for the <code>LLama3.2:latest</code> agent can be found here: <a href=\"https://github.com/DidierRLopes/telegram-text-to-bluesky-post/blob/main/agents/llama_3_2_ollama.py\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/DidierRLopes/telegram-text-to-bluesky-post/blob/main/agents/llama_3_2_ollama.py</a></p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"4-tools-for-the-agent\">4. Tools for the agent<a href=\"https://didierlopes.com/blog/building-an-ai-agent-from-scratch-that-can-post-on-bluesky#4-tools-for-the-agent\" class=\"hash-link\" aria-label=\"Direct link to 4. Tools for the agent\" title=\"Direct link to 4. Tools for the agent\">​</a></h3>\n<p>Finally, I wanted the agent to have access to a few tools, so I created a folder within agents called <code>tools</code> where I added each of these. It can be found <a href=\"https://github.com/DidierRLopes/telegram-text-to-bluesky-post/tree/main/agents/tools\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<div class=\"language-text codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-text codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">agents/</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    llama_3_2_ollama.py</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    phi_3_mini_4k_instruct_ft_on_didier_blog.py</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    ...</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    tools/</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">        grok.py</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">        openbb.py</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">        perplexity.py</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">        ...</span><br></span></code></pre></div></div>\n<p>The implementation for how function calling is performed can be found <a href=\"https://github.com/DidierRLopes/telegram-text-to-bluesky-post/blob/main/agents/llama_3_2_ollama.py\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<p>I didn't do anything fancy, just followed the <a href=\"https://www.llama.com/docs/model-cards-and-prompt-formats/llama3_2\" target=\"_blank\" rel=\"noopener noreferrer\">documentation from Meta</a> and checked that the model would return the function in the right format.</p>\n<p>The implementation is also very straightforward:</p>\n<ul>\n<li>Check what the topic is (that I wrote on Telegram)</li>\n<li>Check if it needs to do research using any of the tools provided<!-- -->\n<ul>\n<li>Currently can only use up to one of them</li>\n</ul>\n</li>\n<li>Uses the topic I wrote on Telegram + the output from the function call to write a post</li>\n</ul>\n<h4 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"41-openbb\">4.1. OpenBB<a href=\"https://didierlopes.com/blog/building-an-ai-agent-from-scratch-that-can-post-on-bluesky#41-openbb\" class=\"hash-link\" aria-label=\"Direct link to 4.1. OpenBB\" title=\"Direct link to 4.1. OpenBB\">​</a></h4>\n<p>I'm biased here, but wanted to throw OpenBB in the mix for financial information.</p>\n<p>In this case there are 2 tools that the agent has access to:</p>\n<p><code>openbb_news_search</code> is used when the agent needs:</p>\n<ul>\n<li>General news articles from various sources</li>\n<li>Latest headlines on a specific topic</li>\n</ul>\n<p><code>openbb_news_on_company_search</code>  is used when the agent needs:</p>\n<ul>\n<li>Specific news articles about a particular company</li>\n<li>Latest information on a company</li>\n</ul>\n<p>Here's how I tested that I could get this data easily:</p>\n<div class=\"language-python codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockTitle_OeMC\"><a href=\"https://github.com/DidierRLopes/telegram-text-to-bluesky-post/blob/main/experiments/test_openbb.py\" target=\"_blank\" rel=\"noopener noreferrer\" style=\"font-weight:bold;color:#0366d6\">/experiments/test_openbb.py</a></div><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-python codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv codeBlockLinesWithNumbering_o6Pm\" style=\"counter-reset:line-count 0\"><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">import</span><span class=\"token plain\"> os</span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">from</span><span class=\"token plain\"> openbb </span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">import</span><span class=\"token plain\"> obb</span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">from</span><span class=\"token plain\"> dotenv </span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">import</span><span class=\"token plain\"> load_dotenv</span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\" style=\"display:inline-block\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\"></span><span class=\"token comment\" style=\"color:rgb(98, 114, 164)\"># Load environment variables</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">load_dotenv</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\" style=\"display:inline-block\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\"></span><span class=\"token comment\" style=\"color:rgb(98, 114, 164)\"># Initialize the OpenBB SDK</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">obb</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">account</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">login</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token plain\">pat</span><span class=\"token operator\">=</span><span class=\"token plain\">os</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">getenv</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"OPENBB_PAT\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\" style=\"display:inline-block\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">def</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(80, 250, 123)\">openbb_news_search</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token plain\">query</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">  </span><span class=\"token triple-quoted-string string\" style=\"color:rgb(255, 121, 198)\">\"\"\"Retrieve news results for a given query using OpenBB's news world endpoint.\"\"\"</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\" style=\"display:inline-block\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">  </span><span class=\"token comment\" style=\"color:rgb(98, 114, 164)\"># Fetch news from the world endpoint</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">  </span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">return</span><span class=\"token plain\"> obb</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">news</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">world</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token plain\">query</span><span class=\"token operator\">=</span><span class=\"token plain\">query</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> limit</span><span class=\"token operator\">=</span><span class=\"token number\">5</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> provider</span><span class=\"token operator\">=</span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"benzinga\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\" style=\"display:inline-block\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">def</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(80, 250, 123)\">openbb_news_on_company_search</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token plain\">query</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">  </span><span class=\"token triple-quoted-string string\" style=\"color:rgb(255, 121, 198)\">\"\"\"Retrieve news results for a given query using OpenBB's news world endpoint.\"\"\"</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\" style=\"display:inline-block\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">  </span><span class=\"token comment\" style=\"color:rgb(98, 114, 164)\"># Fetch news from the company news endpoint</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">  </span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">return</span><span class=\"token plain\"> obb</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">news</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">company</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token plain\">query</span><span class=\"token operator\">=</span><span class=\"token plain\">query</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> limit</span><span class=\"token operator\">=</span><span class=\"token number\">5</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> provider</span><span class=\"token operator\">=</span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"benzinga\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\" style=\"display:inline-block\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\" style=\"display:inline-block\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">if</span><span class=\"token plain\"> __name__ </span><span class=\"token operator\">==</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"__main__\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">  result </span><span class=\"token operator\">=</span><span class=\"token plain\"> openbb_news_search</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"technology\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">  </span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">print</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token plain\">result</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\" style=\"display:inline-block\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">  result </span><span class=\"token operator\">=</span><span class=\"token plain\"> openbb_news_on_company_search</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"Apple\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">  </span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">print</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token plain\">result</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span></span><br></span></code></pre></div></div>\n<p>And the real implementation is <a href=\"https://github.com/DidierRLopes/telegram-text-to-bluesky-post/blob/main/agents/tools/openbb.py\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<h4 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"42-perplexity\">4.2. Perplexity<a href=\"https://didierlopes.com/blog/building-an-ai-agent-from-scratch-that-can-post-on-bluesky#42-perplexity\" class=\"hash-link\" aria-label=\"Direct link to 4.2. Perplexity\" title=\"Direct link to 4.2. Perplexity\">​</a></h4>\n<p><code>perplexity_web_search</code> is used when the agent needs:</p>\n<ul>\n<li>General web information</li>\n<li>Detailed background information</li>\n</ul>\n<p>Here's how I tested that the API worked:</p>\n<div class=\"language-python codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockTitle_OeMC\"><a href=\"https://github.com/DidierRLopes/telegram-text-to-bluesky-post/blob/main/experiments/test_perplexity.py\" target=\"_blank\" rel=\"noopener noreferrer\" style=\"font-weight:bold;color:#0366d6\">/experiments/test_perplexity.py</a></div><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-python codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv codeBlockLinesWithNumbering_o6Pm\" style=\"counter-reset:line-count 0\"><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">import</span><span class=\"token plain\"> os</span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">import</span><span class=\"token plain\"> re</span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">from</span><span class=\"token plain\"> openai </span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">import</span><span class=\"token plain\"> OpenAI</span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">from</span><span class=\"token plain\"> dotenv </span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">import</span><span class=\"token plain\"> load_dotenv</span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\" style=\"display:inline-block\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">def</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(80, 250, 123)\">perplexity_query</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token plain\">messages</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">  client </span><span class=\"token operator\">=</span><span class=\"token plain\"> OpenAI</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">      api_key</span><span class=\"token operator\">=</span><span class=\"token plain\">os</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">getenv</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"PERPLEXITY_API_KEY\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">      base_url</span><span class=\"token operator\">=</span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"https://api.perplexity.ai\"</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">  </span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\" style=\"display:inline-block\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">  response </span><span class=\"token operator\">=</span><span class=\"token plain\"> client</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">chat</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">completions</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">create</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">      model</span><span class=\"token operator\">=</span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"llama-3.1-sonar-small-128k-online\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">      messages</span><span class=\"token operator\">=</span><span class=\"token plain\">messages</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">      stream</span><span class=\"token operator\">=</span><span class=\"token boolean\">False</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">  </span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\" style=\"display:inline-block\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">  </span><span class=\"token comment\" style=\"color:rgb(98, 114, 164)\"># Remove citations using regex</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">  content </span><span class=\"token operator\">=</span><span class=\"token plain\"> response</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">choices</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">[</span><span class=\"token number\">0</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">]</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">message</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">content</span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">  cleaned_content </span><span class=\"token operator\">=</span><span class=\"token plain\"> re</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">sub</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">r'[d+]'</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">''</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> content</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">  </span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">return</span><span class=\"token plain\"> cleaned_content</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">strip</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\" style=\"display:inline-block\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">if</span><span class=\"token plain\"> __name__ </span><span class=\"token operator\">==</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"__main__\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">  </span><span class=\"token comment\" style=\"color:rgb(98, 114, 164)\"># Load environment variables from .env file</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">  load_dotenv</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\" style=\"display:inline-block\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">  </span><span class=\"token comment\" style=\"color:rgb(98, 114, 164)\"># Example message</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">  example_messages </span><span class=\"token operator\">=</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">[</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">      </span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">{</span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"role\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"system\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"content\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"You are a helpful assistant.\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">}</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">      </span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">{</span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"role\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"user\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"content\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"What is the capital of France?\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">}</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">  </span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">]</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\" style=\"display:inline-block\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">  </span><span class=\"token comment\" style=\"color:rgb(98, 114, 164)\"># Run the query</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">  result </span><span class=\"token operator\">=</span><span class=\"token plain\"> perplexity_query</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token plain\">example_messages</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">  </span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">print</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"Response:\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> result</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span></span><br></span></code></pre></div></div>\n<p>And the implementation is <a href=\"https://github.com/DidierRLopes/telegram-text-to-bluesky-post/blob/main/agents/tools/perplexity.py\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<h4 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"43-grok\">4.3. Grok<a href=\"https://didierlopes.com/blog/building-an-ai-agent-from-scratch-that-can-post-on-bluesky#43-grok\" class=\"hash-link\" aria-label=\"Direct link to 4.3. Grok\" title=\"Direct link to 4.3. Grok\">​</a></h4>\n<p><code>grok_x_search</code> is used when the agent needs:</p>\n<ul>\n<li>Recent social media discussions</li>\n<li>Twitter/X specific content</li>\n<li>Real-time reactions and trends</li>\n</ul>\n<p>Here's how I tested the API:</p>\n<div class=\"language-python codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockTitle_OeMC\"><a href=\"https://github.com/DidierRLopes/telegram-text-to-bluesky-post/blob/main/experiments/test_grok.py\" target=\"_blank\" rel=\"noopener noreferrer\" style=\"font-weight:bold;color:#0366d6\">/experiments/test_grok.py</a></div><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-python codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv codeBlockLinesWithNumbering_o6Pm\" style=\"counter-reset:line-count 0\"><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">import</span><span class=\"token plain\"> os</span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">import</span><span class=\"token plain\"> re</span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">from</span><span class=\"token plain\"> openai </span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">import</span><span class=\"token plain\"> OpenAI</span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">from</span><span class=\"token plain\"> dotenv </span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">import</span><span class=\"token plain\"> load_dotenv</span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\" style=\"display:inline-block\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\" style=\"display:inline-block\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">def</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(80, 250, 123)\">grok_x_search</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token plain\">query</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">  </span><span class=\"token triple-quoted-string string\" style=\"color:rgb(255, 121, 198)\">\"\"\"Retrieve web search results for a given query using Grok.\"\"\"</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">  client </span><span class=\"token operator\">=</span><span class=\"token plain\"> OpenAI</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">      api_key</span><span class=\"token operator\">=</span><span class=\"token plain\">os</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">getenv</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"GROK_API_KEY\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">      base_url</span><span class=\"token operator\">=</span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"https://api.x.ai/v1\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">  </span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">  messages </span><span class=\"token operator\">=</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">[</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">      </span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">{</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">          </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"role\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"system\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">          </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"content\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">              </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"You are a helpful assistant with access to up-to-date information \"</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">              </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"from the web. You can provide context on various topics, especially \"</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">              </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"recent events and developments. Your task is to provide enough \"</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">              </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"content so the user can craft an informative and engaging post \"</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">              </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"based on the given query.\"</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">          </span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">      </span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">}</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">      </span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">{</span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"role\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"user\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"content\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"> query</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">}</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">  </span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">]</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\" style=\"display:inline-block\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">  response </span><span class=\"token operator\">=</span><span class=\"token plain\"> client</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">chat</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">completions</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">create</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">      model</span><span class=\"token operator\">=</span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"grok-beta\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">      messages</span><span class=\"token operator\">=</span><span class=\"token plain\">messages</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">      stream</span><span class=\"token operator\">=</span><span class=\"token boolean\">False</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">  </span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\" style=\"display:inline-block\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">  </span><span class=\"token comment\" style=\"color:rgb(98, 114, 164)\"># Remove citations using regex</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">  content </span><span class=\"token operator\">=</span><span class=\"token plain\"> response</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">choices</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">[</span><span class=\"token number\">0</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">]</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">message</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">content</span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">  cleaned_content </span><span class=\"token operator\">=</span><span class=\"token plain\"> re</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">sub</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">r\"[d+]\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> content</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">  </span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">return</span><span class=\"token plain\"> cleaned_content</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">strip</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\" style=\"display:inline-block\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">if</span><span class=\"token plain\"> __name__ </span><span class=\"token operator\">==</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"__main__\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">  </span><span class=\"token comment\" style=\"color:rgb(98, 114, 164)\"># Load environment variables from .env file</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">  load_dotenv</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">  </span><span class=\"token comment\" style=\"color:rgb(98, 114, 164)\"># Run the query</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">  result </span><span class=\"token operator\">=</span><span class=\"token plain\"> grok_x_search</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"What are the latest developments in AI?\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token plain\"></span></span><br></span><span class=\"token-line codeLine_lJS_\" style=\"color:#F8F8F2\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">  </span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">print</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"Response:\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> result</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span></span><br></span></code></pre></div></div>\n<p>And the implementation is <a href=\"https://github.com/DidierRLopes/telegram-text-to-bluesky-post/blob/main/agents/tools/grok.py\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"5-put-it-all-together\">5. Put it all together<a href=\"https://didierlopes.com/blog/building-an-ai-agent-from-scratch-that-can-post-on-bluesky#5-put-it-all-together\" class=\"hash-link\" aria-label=\"Direct link to 5. Put it all together\" title=\"Direct link to 5. Put it all together\">​</a></h3>\n<p>Finally, I merged it all together in <a href=\"https://github.com/DidierRLopes/telegram-text-to-bluesky-post/blob/main/bluesky-agent.py\" target=\"_blank\" rel=\"noopener noreferrer\">this file</a>.</p>\n<p>This is what the architecture looks like:</p>\n<p align=\"center\"><img width=\"900\" src=\"https://didierlopes.com/blog/2025-01-04-building-an-ai-agent-from-scratch-that-can-post-on-bluesky.webp\"></p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"conclusion\">Conclusion<a href=\"https://didierlopes.com/blog/building-an-ai-agent-from-scratch-that-can-post-on-bluesky#conclusion\" class=\"hash-link\" aria-label=\"Direct link to Conclusion\" title=\"Direct link to Conclusion\">​</a></h2>\n<p>I enjoyed working on this project. It didn't take me much time to do it, and allowed me to learn:</p>\n<ul>\n<li>Utilizing Telegram API and bot convention</li>\n<li>Posting on Bluesky</li>\n<li>Playing with local models through Ollama</li>\n<li>Using xAI API for the first time - made extremely easy with OpenAI compatibility</li>\n</ul>\n<p>The architecture I went with offers several advantages:</p>\n<ol>\n<li><strong>Privacy</strong>: Using a local LLM means sensitive data stays on your machine</li>\n<li><strong>Customization</strong>: The system prompt can be easily modified to change the AI's tone</li>\n<li><strong>Reliability</strong>: Asynchronous design prevents the bot from hanging</li>\n<li><strong>Scalability</strong>: The modular design makes it easy to add new tools or models</li>\n</ol>\n<br>\n<p>This hasn't been heavily tested - just enough for me to test that it works end-to-end.</p>\n<p>Over the next few days I'm going to play with <a href=\"https://github.com/elizaOS/eliza\" target=\"_blank\" rel=\"noopener noreferrer\">Eliza from ai16z</a> which I learned about only after having this implemented. It looks like it has a similar concept but agents \"live\" natively on X.</p>\n<p>Any feedback please let me know!</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/building-an-ai-agent-from-scratch-that-can-post-on-bluesky",
            "title": "Building an AI agent from scratch that can post on bluesky",
            "summary": "A practical guide to building an AI agent that processes Telegram messages through a local LLM, gathers context from various sources (OpenBB, Perplexity, Grok), and automatically posts content to Bluesky.",
            "date_modified": "2025-01-04T00:00:00.000Z",
            "tags": [
                "ai",
                "agent",
                "python",
                "open-source",
                "llm",
                "ollama",
                "telegram",
                "bluesky",
                "api"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/ai-chatbots-wont-revolutionize-finance-but-intelligent-workspaces-will",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2024-12-27-ai-chatbots-wont-revolutionize-finance-but-intelligent-workspaces-will.webp\"></p>\n<p>Why the future of financial analysis isn't about chatbots, but about intelligent workspaces that combine your data, tools, and AI exactly when you need them.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>When ChatGPT launched, everyone rushed to build financial chatbots. But they missed two fundamental truths:</p>\n<ul>\n<li>The best AI model is useless without access to your data.</li>\n<li>Access to data isn't enough - AI needs to handle complete workflows, not just conversations.</li>\n</ul>\n<p>The limitations of most financial chatbots:</p>\n<ol>\n<li>They only work on a specific dataset (e.g 10-K/10-Q)</li>\n<li>They can't handle complex financial workflows</li>\n<li>They force analysts to work in an unnatural chat interface</li>\n</ol>\n<br>\n<p>Here's how OpenBB addresses these challenges:</p>\n<p>First, we ensure comprehensive data access:</p>\n<ul>\n<li>Run everything on-premise or in your VPC</li>\n<li>Connect any data source: internal files, APIs, third-party feeds, market data - anything</li>\n<li>Use a universal data layer that standardizes everything (whether it's CSV, Excel, Snowflake, or APIs)</li>\n</ul>\n<p>But the real innovation?</p>\n<p>We're building AI differently.</p>\n<p>Instead of forcing analysts to chat with a bot, we're embedding intelligence directly into their workspace.</p>\n<p>Think dashboards with widgets, not chat windows. Data visualization, not text conversations.</p>\n<p>This is exactly what Kimberly Tan (partner @ a16z) predicted in <a href=\"https://a16z.com/big-ideas-in-tech-2025/\" target=\"_blank\" rel=\"noopener noreferrer\">her analysis</a>:</p>\n<blockquote>\n<p><em>\"Chat was the first experimental interface — now I expect there will be new, novel interaction mechanisms. In this phase, AI agents will be able to take direct action in the workflow, and the UI will be reimagined for humans to review work or do QA.\"</em></p>\n</blockquote>\n<br>\n<p>The result?</p>\n<p align=\"center\"><img width=\"1200\" src=\"https://didierlopes.com/blog/2024-12-27-ai-chatbots-wont-revolutionize-finance-but-intelligent-workspaces-will.webp\"></p>\n<p>A workspace where:</p>\n<ul>\n<li>AI appears only when needed (for insights, summaries, or generating visualizations)</li>\n<li>Firms can adopt AI at their own pace</li>\n<li>Analysts keep their familiar workflows while gaining AI superpowers</li>\n</ul>\n<p>Let me show you this in action.</p>\n<p>Last week, I shared how <a href=\"https://x.com/mattmaximo1/status/1869413550210625818\" target=\"_blank\" rel=\"noopener noreferrer\">Matt from VanEck</a> built a powerful dashboard integrating multiple distinct data sources on OpenBB. Post with comments can be found <a href=\"https://www.linkedin.com/posts/didier-lopes_today-i-saw-a-glimpse-of-the-future-matt-activity-7275174801860636672-qoy4?utm_source=share&amp;utm_medium=member_desktop\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<p>I only showed a screenshot of this dashboard with data.</p>\n<p>There was no sign of AI in it.</p>\n<p>However, if I had simply pressed shortcut \"Ctrl+L\", the copilot window would have opened and I would have been able to natively interact with the data - and generate new data from it.</p>\n<p align=\"center\"><img width=\"1200\" src=\"https://didierlopes.com/blog/2024-12-27-ai-chatbots-wont-revolutionize-finance-but-intelligent-workspaces-will_1.webp\"></p>\n<p>This demonstrates that the future of financial AI isn't about chatbots - it's about intelligent workspaces.</p>\n<p>As <a href=\"https://x.com/pyquantnews\" target=\"_blank\" rel=\"noopener noreferrer\">Jason from PyQuantNews</a> astutely observes: <em>\"OpenBB solves the data aggregation and centralization challenge without relying on AI, creating a ton of value from it. And then, you allow users to utilize AI in their workflows as they see fit.\"</em></p>\n<p>This isn't just another AI product.</p>\n<p>It's the future of financial analysis - where AI enhances your workspace instead of replacing it.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/ai-chatbots-wont-revolutionize-finance-but-intelligent-workspaces-will",
            "title": "AI chatbots won't revolutionize finance, but intelligent workspaces will",
            "summary": "Beyond the AI hype - why the future of financial analysis isn't about chatbots, but about intelligent workspaces that combine your data, tools, and AI exactly when you need them.",
            "date_modified": "2024-12-27T00:00:00.000Z",
            "tags": [
                "openbb",
                "ai",
                "fintech",
                "workspaces",
                "future-of-finance",
                "financial-analytics",
                "chatbots",
                "ui",
                "ux"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/openbb-and-our-global-reach-since-leaving-beta",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2024-12-22-openbb-and-our-global-reach-since-leaving-beta.webp\"></p>\n<p>This is how OpenBB is reaching users worldwide with Chrome's translation features, making financial analytics accessible in multiple languages and expanding our presence across 84% of countries since launch.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>Since our launch on October 7th, we realized that while the majority of our audience is based in the US - we have users utilizing OpenBB from all around the globe.</p>\n<p>In fact, if we count sign ups since October we have a 84% country representation.</p>\n<p>Today, most of the top financial firms have reached out to OpenBB to learn more. Either because they heard about us from others, or had someone internally speaking about OpenBB.</p>\n<p>However - it has also happened having conversation with firms that focus so much on emerging markets (e.g. LatAm) that they speak mostly Portuguese or Spanish.</p>\n<p>So, here I am showing you that you can utilize the Google Translate feature that comes with Google Chrome in under 10 seconds to have our product being translated in real-time to your language of choice.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2024-12-22-openbb-and-our-global-reach-since-leaving-beta_1.webp\"></p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2024-12-22-openbb-and-our-global-reach-since-leaving-beta_2.webp\"></p>\n<p>I've been playing with it in Portuguese, and it works <em>surprisingly</em> well.</p>\n<p>This even means that you can utilize your AI copilot in your language of choice, which is mind blowing!</p>\n<p>It's this Christmas that I will be able to convert my family to DAU. 😃</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/openbb-and-our-global-reach-since-leaving-beta",
            "title": "OpenBB and our global reach since leaving beta",
            "summary": "This is how OpenBB is reaching users worldwide with Chrome's translation features, making financial analytics accessible in multiple languages and expanding our presence across 84% of countries since launch.",
            "date_modified": "2024-12-22T00:00:00.000Z",
            "tags": [
                "openbb",
                "fintech",
                "growth",
                "global-audience",
                "internationalization",
                "accessibility",
                "translation",
                "languages"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/why-ai-analysts-need-human-like-workspaces-not-just-chat-interfaces",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2024-12-20-why-ai-analysts-need-human-like-workspaces-not-just-chat-interfaces.webp\"></p>\n<p>Why I believe AI agents need the same comprehensive workspace tools as human analysts, moving beyond simple chat interfaces to enable true financial research and analytics.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>This week, Insight Partners published <a href=\"https://www.insightpartners.com/ideas/state-of-the-ai-agent-ecosystem-use-cases-and-learnings-for-technology-builders-and-buyers/\" target=\"_blank\" rel=\"noopener noreferrer\">\"The state of the AI Agents ecosystem: The tech, use cases, and economics\"</a> which mentions OpenBB on the map in terms of Financial Services AI agents.</p>\n<p>I'd like to explain our flavor of AI analyst.</p>\n<p>An AI agent is defined as \"a program that can interact with its environment, collect data, and use the data to perform self-determined tasks to meet predetermined goals\".</p>\n<p>If I were to describe the role of an Analyst I could use that exact same sentence, except that I wouldn't use \"program\" but \"human\".</p>\n<p>Yet most companies and products out there are focusing on the data and forgetting about the interface.</p>\n<p>If the job to be done by an AI agent is the same as the human agent - why aren't we starting from the assumption that they need the same tools and interface as a human analyst would.</p>\n<p>I mean, I don't see financial analysts spending their day doing analysis &amp; research on Slack or on a chat-only interface.</p>\n<p>This is where we differ and where we decided to take the longer path in doing what's right.</p>\n<p>No shortcuts.</p>\n<p>Yes, our AI agent (or the one our users bring) has access to their own data.</p>\n<p>But more importantly, it is interconnected with a workspace, effectively having the same type of capabilities that an analyst would so it can truly perform research and analytics.</p>\n<p>The goal is actually straightforward:</p>\n<p>The AI agent should be able to do anything and everything that a user can with a mouse and keyboard.</p>\n<p>That includes:</p>\n<ul>\n<li>Extracting insights from multiple datasets</li>\n<li>Adding a particular widget to a dashboard</li>\n<li>Creating a dashboard from scratch based on data available</li>\n<li>Run a particular prediction model with pre-define parameters</li>\n<li>Collaborating on a dashboard with a colleague</li>\n<li>Having access to the internet to add research notes to the dashboard</li>\n<li>Join datasets efficiently</li>\n<li>Write SQL queries to extract particular data from a data warehouse</li>\n<li>etc...</li>\n</ul>\n<p>Agree or disagree?</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/why-ai-analysts-need-human-like-workspaces-not-just-chat-interfaces",
            "title": "Why AI analysts need human-like workspaces, not just chat interfaces",
            "summary": "Why I believe AI agents need the same comprehensive workspace tools as human analysts, moving beyond simple chat interfaces to enable true financial research and analytics.",
            "date_modified": "2024-12-20T00:00:00.000Z",
            "tags": [
                "openbb",
                "ai",
                "analyst",
                "agent",
                "workspace",
                "fintech",
                "user-interface",
                "future-of-ai"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/today-i-saw-a-glimpse-of-the-future",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2024-12-18-today-i-saw-a-glimpse-of-the-future.webp\"></p>\n<p>My friend Matt, from VanEck, built a backend with data from Coingecko, Velodata, Artemis, CCdata, Glassnode, MSTR Tracker, Telegram and Google - all in OpenBB.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p><a href=\"https://x.com/mattmaximo1\" target=\"_blank\" rel=\"noopener noreferrer\">Matt Maximo</a> has been building a backend with data from Coingecko, Velodata, Artemis, CCdata, Glassnode, MSTR Tracker, Telegram and Google.</p>\n<p>However, he didn't find the best product where he could:</p>\n<ol>\n<li>Bring all this data into one interface</li>\n<li>Leverage an intelligence layer on top</li>\n<li>Collaborate with his team on it</li>\n</ol>\n<br>\n<p>Until he did.</p>\n<p>With our free tier - Matt was able to single-handedly create almost 50 different data widgets that he (and his team) will be able to access seamlessly on OpenBB.</p>\n<p>As we shift to firms being more in control of their data, and with the clear gains from having an additional intelligence layer on top of that data - the need for OpenBB in the market has never been clearer.</p>\n<p>Shifting the control back to financial firms.</p>\n<p>More open. More adaptable.</p>\n<p>If you want help on connecting your own backend (crypto or other) to OpenBB - reach out to myself and team.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/today-i-saw-a-glimpse-of-the-future",
            "title": "Today I saw a glimpse of the future",
            "summary": "My friend Matt, from VanEck, built a backend with data from Coingecko, Velodata, Artemis, CCdata, Glassnode, MSTR Tracker, Telegram and Google - all in OpenBB.",
            "date_modified": "2024-12-18T00:00:00.000Z",
            "tags": [
                "openbb",
                "ai",
                "fintech",
                "crypto",
                "data-aggregation",
                "customization",
                "open-source",
                "future-of-finance"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/why-we-got-rid-of-pips-at-openbb",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2024-11-09-why-we-got-rid-of-pips-at-openbb.webp\"></p>\n<p>At OpenBB, we removed Performance Improvement Plans (PIPs) in an attempt to increase the company's talent density pool rate.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"how-did-we-get-here\">How did we get here?<a href=\"https://didierlopes.com/blog/why-we-got-rid-of-pips-at-openbb#how-did-we-get-here\" class=\"hash-link\" aria-label=\"Direct link to How did we get here?\" title=\"Direct link to How did we get here?\">​</a></h2>\n<p>We are currently 16 FTE and since the company started 3 years ago, we’ve let go 15 people.</p>\n<p>This means we’re letting go of more than 1 person a quarter since the start of OpenBB.</p>\n<p>Most people had a 3-week PIP process before their departures. But out of the 15 PIPs done, only one was successful. All the others have resulted in a contract termination.</p>\n<p>That’s a success rate of less than 7%, which is extremely low.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"statistics\">Statistics<a href=\"https://didierlopes.com/blog/why-we-got-rid-of-pips-at-openbb#statistics\" class=\"hash-link\" aria-label=\"Direct link to Statistics\" title=\"Direct link to Statistics\">​</a></h3>\n<p>If we go into the machine learning domain and have a model that predicts that a team member who gets into a PIP is let go every time - this is the classification matrix that we would have.</p>\n<p align=\"center\"><img width=\"900\" src=\"https://didierlopes.com/blog/2024-11-09-why-we-got-rid-of-pips-at-openbb_02.webp\"></p>\n<p>Which has:</p>\n<ul>\n<li>\n<p>93.3% precision - answers: of all the people predicted to be let go (15), how many were let go? (14)</p>\n</li>\n<li>\n<p>100% recall - answers: of all the people that were let go (14), how many were predicted correctly (14)</p>\n</li>\n</ul>\n<p>Now, this isn’t the full story.</p>\n<p>This is the equivalent of a physics book treating an object as a point mass, considering the body as perfectly rigid or assuming the system is isolated with no external forces.</p>\n<p>So what are the other things to consider? Let’s separate these time-wise:</p>\n<ol>\n<li>\n<p>Before a PIP happens</p>\n</li>\n<li>\n<p>During the PIP</p>\n</li>\n<li>\n<p>After the PIP</p>\n</li>\n</ol>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"before-a-pip\">Before a PIP<a href=\"https://didierlopes.com/blog/why-we-got-rid-of-pips-at-openbb#before-a-pip\" class=\"hash-link\" aria-label=\"Direct link to Before a PIP\" title=\"Direct link to Before a PIP\">​</a></h2>\n<p>Before someone starts a PIP, their performance has already been subpar.</p>\n<p>By definition, performance is a lagging indicator, which means you are already late when you catch this person not pulling as much value as others.</p>\n<p>Particularly when you consider that the person who would be initiating the PIP is the team lead (TL)/manager and isn’t working as closely with this person as others on a daily basis. Hence, coworkers are likely to see firsthand this suboptimal performance in advance of the team lead or manager.</p>\n<p>So, the suboptimal performance from this person over a few days or weeks is likely to go unnoticed and slow down the company.</p>\n<p>In addition, individual contributors (ICs) who work closely with this person are likely to notice this before the TL/manager, thus impacting their motivation.</p>\n<p><em><strong>\"If this person can get the same compensation as I do for average work, why am I putting in so much time and effort?\"</strong></em></p>\n<p>Honestly, if there’s one thing that I’ve learned, it’s that A players get motivated by other A players (“A players attract A players”).</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"during-a-pip\">During a PIP<a href=\"https://didierlopes.com/blog/why-we-got-rid-of-pips-at-openbb#during-a-pip\" class=\"hash-link\" aria-label=\"Direct link to During a PIP\" title=\"Direct link to During a PIP\">​</a></h2>\n<p>A PIP takes time. <strong>A LOT of it.</strong></p>\n<p>And that’s the one thing that startups don’t have.</p>\n<p>Imagine that you have the following org:</p>\n<p align=\"center\"><img width=\"900\" src=\"https://didierlopes.com/blog/2024-11-09-why-we-got-rid-of-pips-at-openbb_03.webp\"></p>\n<p>If an IC is underperforming, the TL will discuss it with the IC in advance.</p>\n<p>Then the team lead may ask for feedback from other ICs who work with the IC in question.</p>\n<p>After that, the TL will talk with the Director about this before initiating the PIP.</p>\n<p>Then the Director will mention this to the CEO of the company.</p>\n<p>The CEO will likely want to talk with the team lead about this, given that in an organization of 15 people, each team member accounts for more than 5% of the org.</p>\n<p>Now, you may be thinking, “But this happens before the PIP”.</p>\n<p>This happens before and continues throughout the entire PIP. But, during the PIP, it’s even worse because there are regular meetings for a shorter feedback loop, and there needs to be documentation on the progress.</p>\n<p>So yes, this not only takes a lot of time, but it’s also a distraction to the team.</p>\n<p>And that’s the other thing that companies need: “focus”.</p>\n<p>You can’t fully focus at 100% when you know that someone is “fighting” for their job. And not being able to focus impacts each individual’s performance.</p>\n<p>So this inefficiency ends up spreading across the team.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"after-the-pip\">After the PIP<a href=\"https://didierlopes.com/blog/why-we-got-rid-of-pips-at-openbb#after-the-pip\" class=\"hash-link\" aria-label=\"Direct link to After the PIP\" title=\"Direct link to After the PIP\">​</a></h2>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"needs-to-be-let-go\">Needs to be let go<a href=\"https://didierlopes.com/blog/why-we-got-rid-of-pips-at-openbb#needs-to-be-let-go\" class=\"hash-link\" aria-label=\"Direct link to Needs to be let go\" title=\"Direct link to Needs to be let go\">​</a></h3>\n<p>Ok, someone was underperforming and needs to be let go.</p>\n<p>The company needs to figure out:</p>\n<ul>\n<li>\n<p>How many options this person has vested and handle the paperwork if they want to buy them</p>\n</li>\n<li>\n<p>Whether they have company equipment that needs to be returned</p>\n</li>\n<li>\n<p>What the severance package will be</p>\n</li>\n<li>\n<p>How to handle the news and how the team will react</p>\n</li>\n</ul>\n<p>Again, this will be a distraction for at least an additional week and will affect other team members, who may be surprised by this.</p>\n<p>Particularly because, most of the time, they aren’t aware that the PIP is happening and from their perspective, someone they liked to work with was let go.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"has-a-successful-pip\">Has a successful PIP<a href=\"https://didierlopes.com/blog/why-we-got-rid-of-pips-at-openbb#has-a-successful-pip\" class=\"hash-link\" aria-label=\"Direct link to Has a successful PIP\" title=\"Direct link to Has a successful PIP\">​</a></h3>\n<p>Let’s be honest, these cases are very rare.</p>\n<p>Not just at OpenBB. I’ve spoken with other founders, and this is the same feedback I’ve received.</p>\n<p>But let’s ignore that, we already mentioned it at the start.</p>\n<p>Someone on a PIP—almost by definition—isn’t a high performer. They could be a high performer in some parts of the job, but not as a whole. However, this is the exception, not the rule.</p>\n<p>The rule, often, is that this person has been doing just enough to be competent at the company—but not excel. Then, over a period of time, due to internal reasons, lack of motivation, etc., they fall below that threshold.</p>\n<p>This means that even after a successful PIP, you are putting all of these resources toward getting—not a high performer, but a B+ player.</p>\n<p>And ultimately, this is why we are getting rid of the PIP at OpenBB.</p>\n<p>Being <strong>“good enough”</strong> isn’t the culture we want for OpenBB and doesn’t represent our team today. If you let the bar slip, you won’t even realize it until it’s too late.</p>\n<p>Again, performance is a lagging indicator and can have both positive and negative effects on the team—so it’s important to protect the team from poor performers.</p>\n<p>There are two exceptions to this:</p>\n<p><strong>1. Imagine that this person can turn their output into 4x, imagine they had a wake-up call.</strong></p>\n<p>Several questions need to be asked:</p>\n<ul>\n<li>\n<p>If this person can perform at this level, why weren't they doing it before?</p>\n</li>\n<li>\n<p>How long will they maintain this level of performance?</p>\n</li>\n<li>\n<p>Will we need to have another serious conversation to get this person to reach this level of competency again at a later stage?</p>\n</li>\n<li>\n<p>Will they always resent the company because of the PIP?</p>\n</li>\n</ul>\n<p>It all boils down to this: if this person isn’t motivated by what we’re building, regardless of their skill set, they weren’t a good fit in the first place.</p>\n<p>We’re fortunate to have a pipeline of people applying for positions at OpenBB, not just for the money but for the product and the mission of the company.</p>\n<p><strong>2. The person is a high performer but has been performing poorly in some areas of the job (e.g. communications, testing, documentation, …)</strong></p>\n<p>This person had likely received feedback multiple times, but the PIP made it more real: <em>“This is what we are looking for in a person for your role; you have 2-3 weeks to prove that you can double down on your weaknesses and reach the level the team needs you to be at.”</em></p>\n<p>This is what happened to us, and the person improved significantly, so much so that they are now a core part of who OpenBB is today.</p>\n<p>This success story was one of the main reasons we continued doing PIPs.</p>\n<p>But the likelihood of it happening again is so low that it’s not worth keeping PIP to look for another success story like this one.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"so-whats-next\">So what’s next?<a href=\"https://didierlopes.com/blog/why-we-got-rid-of-pips-at-openbb#so-whats-next\" class=\"hash-link\" aria-label=\"Direct link to So what’s next?\" title=\"Direct link to So what’s next?\">​</a></h2>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"how-we-think-about-talent-level-at-openbb\">How we think about talent level at OpenBB<a href=\"https://didierlopes.com/blog/why-we-got-rid-of-pips-at-openbb#how-we-think-about-talent-level-at-openbb\" class=\"hash-link\" aria-label=\"Direct link to How we think about talent level at OpenBB\" title=\"Direct link to How we think about talent level at OpenBB\">​</a></h3>\n<p>Let’s say you define company’s talent value as the sum of the talent of each individual divided by the total number of team members.</p>\n<p>There are two ways to increase this value:</p>\n<ul>\n<li>\n<p>Hire people who are above OpenBB’s talent level</p>\n</li>\n<li>\n<p>Let go of people who fall below the talent level</p>\n</li>\n</ul>\n<p>Or, ideally, do both.</p>\n<p>The problem is that for the first option, you often need <strong>a LOT</strong> of capital.</p>\n<p>For the second, you don’t. Not only that but letting go of low performers will accomplish two things simultaneously:</p>\n<ul>\n<li>\n<p>Increase OpenBB’s talent level immediately.</p>\n</li>\n<li>\n<p>Free up resources that can be invested in someone above OpenBB’s current talent value (assuming that companies should always seek high performers and avoid settling for underperformers).</p>\n</li>\n</ul>\n<p>And that’s why removing PIPs leads to an increase in the company’s talent level. You’re not just increasing the talent level once, but likely twice.</p>\n<p>Here’s an example:</p>\n<p>Imagine we have 5 people at OpenBB with talent scores of 2, 7, 7, 7, and 9. Then OpenBB’s talent level is:</p>\n<p>(2+7+7+7+9)/5 = 6.4</p>\n<p>If we let go of the employee with a talent score of 2, our talent level becomes 7.4. Then, if we bring in someone with a score of 8 using the same resources, that talent level increases to 7.6.</p>\n<p>You get the idea.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"what-the-team-can-expect\">What the team can expect?<a href=\"https://didierlopes.com/blog/why-we-got-rid-of-pips-at-openbb#what-the-team-can-expect\" class=\"hash-link\" aria-label=\"Direct link to What the team can expect?\" title=\"Direct link to What the team can expect?\">​</a></h3>\n<p>Full transparency.</p>\n<p>We want to build a culture where feedback is an ever-present element, and we don’t need to wait for performance reviews to give feedback that can substantially improve team performance and push the company forward.</p>\n<p>In fact, not sharing this feedback puts the company in a worse position, and it is your duty to share it. But do so with candor, in a constructive manner that keeps the team member motivated.</p>\n<p>However, each team member must care. This means you can’t rely solely on your team lead to give you feedback every day—you need to ask for it regularly. That’s the best way for you to grow.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"final-notes\">Final notes<a href=\"https://didierlopes.com/blog/why-we-got-rid-of-pips-at-openbb#final-notes\" class=\"hash-link\" aria-label=\"Direct link to Final notes\" title=\"Direct link to Final notes\">​</a></h2>\n<p>We made this decision after reading <em>No Rules Rules: Netflix and the Culture of Reinvention</em>, where they also removed PIPs.</p>\n<p>Unlike Netflix, we don’t have the resources to:</p>\n<ul>\n<li>\n<p>Pay top of the market</p>\n</li>\n<li>\n<p>Offer a generous severance</p>\n</li>\n</ul>\n<p>We still pay good salaries, just not enough to compete with public companies. This means we need to spend much more time finding diamonds in the rough.</p>\n<p>And that’s why we have a higher turnover; finding diamonds in the rough is much riskier.</p>\n<p>In any case, I think optimizing to pay top of the market is misguided—at least for startups—as it incentivizes the wrong type of talent.</p>\n<p>It incentivizes mercenaries instead of missionaries.</p>\n<p>At an early stage, you need people who want a lot of ownership and autonomy, who are excited to work with a team and on a product they believe in, and who have a chip on their shoulders.</p>\n<p>Regardless of the startup, I have yet to see someone with this mentality who doesn’t end up being successful.</p>\n<p><strong>Note</strong>: Most of the people who were let go would be considered good employees in most companies today, and they had strong referrals. But companies have different types of needs that evolve over time, and as founders, it’s our role to look at the company as a whole and understand what it needs at the moment and, more importantly, what it will need in the coming months and years.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/why-we-got-rid-of-pips-at-openbb",
            "title": "Why we got rid of PIPs at OpenBB",
            "summary": "My thoughts on how removing PIPs can increase the company talent level",
            "date_modified": "2024-11-09T00:00:00.000Z",
            "tags": [
                "openbb",
                "management",
                "leadership",
                "talent",
                "hiring",
                "performance",
                "company-culture",
                "startups"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/implement-feedback-loops-everywhere-you-can",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2024-10-25-implement-feedback-loops-everywhere-you-can.webp\"></p>\n<p>Maximizing team transparency through focused feedback sessions.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>A couple of months ago, my co-founder came to NYC for our board meeting.</p>\n<p>During that week, we took a day to sync up with everyone on the team—literally. We had 14 conversations, each lasting up to 30 minutes. Apart from lunch, we did all these back-to-back.</p>\n<p>The goal of this exercise was 2-fold:</p>\n<ul>\n<li>\n<p>Check up on the team. Basically, a more in-depth version of:\n<a href=\"https://openbb.co/company/open/team\" target=\"_blank\" rel=\"noopener noreferrer\">https://openbb.co/company/open/team</a></p>\n</li>\n<li>\n<p>Have the team share anything they want with leadership or ask any questions openly.</p>\n</li>\n</ul>\n<p align=\"center\"><img width=\"900\" src=\"https://didierlopes.com/blog/2024-10-25-implement-feedback-loops-everywhere-you-can_2.webp\"></p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"structure\">Structure<a href=\"https://didierlopes.com/blog/implement-feedback-loops-everywhere-you-can#structure\" class=\"hash-link\" aria-label=\"Direct link to Structure\" title=\"Direct link to Structure\">​</a></h2>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"part-1---20-minutes\">Part 1 - 20 minutes<a href=\"https://didierlopes.com/blog/implement-feedback-loops-everywhere-you-can#part-1---20-minutes\" class=\"hash-link\" aria-label=\"Direct link to Part 1 - 20 minutes\" title=\"Direct link to Part 1 - 20 minutes\">​</a></h3>\n<p>For the first 20 minutes, we asked the following questions to each team member:</p>\n<ol>\n<li>\n<p>How do you feel working for OpenBB today?</p>\n</li>\n<li>\n<p>What do you enjoy the most about working at this company?</p>\n</li>\n<li>\n<p>Who do you get along the best? and why?</p>\n</li>\n<li>\n<p>Who do you feel like you have a not-so-close relationship with? and why?</p>\n</li>\n<li>\n<p>What does your day-to-day look like?</p>\n</li>\n<li>\n<p>How would you describe the relationship with your manager/team lead?</p>\n</li>\n<li>\n<p>It's 2028 and OpenBB didn't make it. What are potential reasons that you would bet on that lead to this?</p>\n</li>\n<li>\n<p>If you had to tell us what your biggest achievement is since being in the company, which one would you pick?</p>\n</li>\n<li>\n<p>What was your lowest moment during company time - and why? What could we have done better?</p>\n</li>\n<li>\n<p>(for managers/team leads) How do you feel about the team you have today?</p>\n</li>\n</ol>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"part-2---10-minutes\">Part 2 - 10 minutes<a href=\"https://didierlopes.com/blog/implement-feedback-loops-everywhere-you-can#part-2---10-minutes\" class=\"hash-link\" aria-label=\"Direct link to Part 2 - 10 minutes\" title=\"Direct link to Part 2 - 10 minutes\">​</a></h3>\n<p>During the last 10 minutes, the team could ask us about anything.</p>\n<p>Funnily enough, we learned just as much (if not more) from the questions the team asked than the ones from Part 1.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"results\">Results<a href=\"https://didierlopes.com/blog/implement-feedback-loops-everywhere-you-can#results\" class=\"hash-link\" aria-label=\"Direct link to Results\" title=\"Direct link to Results\">​</a></h2>\n<p>Lack of focus is the biggest risk/challenge that we face as a company.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"culture\">Culture<a href=\"https://didierlopes.com/blog/implement-feedback-loops-everywhere-you-can#culture\" class=\"hash-link\" aria-label=\"Direct link to Culture\" title=\"Direct link to Culture\">​</a></h3>\n<ul>\n<li>\n<p>Handbook is important (folks didn't know about personal development budget, PIP, etc…)</p>\n</li>\n<li>\n<p>The team's main reasons for being happy at OpenBB are autonomy, ownership, smart team, transparency and freedom - very aligned with our values.</p>\n</li>\n<li>\n<p>Remote work is a benefit that more people should take advantage of. Celebrate it even more.</p>\n</li>\n<li>\n<p>It's vital to set boundaries when overworking and know when to decompress to avoid burnout</p>\n</li>\n</ul>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"management\">Management<a href=\"https://didierlopes.com/blog/implement-feedback-loops-everywhere-you-can#management\" class=\"hash-link\" aria-label=\"Direct link to Management\" title=\"Direct link to Management\">​</a></h3>\n<ul>\n<li>\n<p>It's key to consider that each person has different preferences in terms of management style - execution vs contributing to discussion.</p>\n</li>\n<li>\n<p>1:1s are essential and everyone should have them set.</p>\n</li>\n<li>\n<p>1:1s should be focused on the direct report and not necessarily on tasks at hand. Several people highlighted that they felt that their manager cared about them based on conversations about their personal life and personal development.</p>\n</li>\n<li>\n<p>Feedback should go both ways, the manager/leader appreciates when feedback is provided.</p>\n</li>\n<li>\n<p>Setting up expectations clearly for each individual is critical. People appreciate when they know exactly what is expected of them, so they understand how their value is perceived from the company's perspective.</p>\n</li>\n</ul>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"rituals\">Rituals<a href=\"https://didierlopes.com/blog/implement-feedback-loops-everywhere-you-can#rituals\" class=\"hash-link\" aria-label=\"Direct link to Rituals\" title=\"Direct link to Rituals\">​</a></h3>\n<ul>\n<li>\n<p>Monthly update emails are very good. Sometimes even more details would be better.</p>\n</li>\n<li>\n<p>Some people are so focused on execution that they try to protect their time at all costs. It's important to respect this decision and default to async text-based conversations instead of setting up a meeting</p>\n</li>\n<li>\n<p>Dogfood the product from people from different backgrounds is important as it gives different points of view that we can leverage to make our product better</p>\n</li>\n</ul>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"communicatiions\">Communicatiions<a href=\"https://didierlopes.com/blog/implement-feedback-loops-everywhere-you-can#communicatiions\" class=\"hash-link\" aria-label=\"Direct link to Communicatiions\" title=\"Direct link to Communicatiions\">​</a></h3>\n<ul>\n<li>\n<p>Be aware of different comms styles throughout org. In general, people have shared that they appreciate when others send them a DM with feedback based on a conversation in a public channel.</p>\n</li>\n<li>\n<p>Sometimes team members need to put themselves in the shoes of other people first instead of defaulting to defence.</p>\n</li>\n<li>\n<p>We shouldn't compromise on quality. We should aim to agree first on the best solution and then adapt if there's a lack of resources, but knowing what the best solution is and what is the trade-off that is being made</p>\n</li>\n<li>\n<p>When a conversation is taking a few messages back and forth, sometimes a quick huddle should be done</p>\n</li>\n<li>\n<p>Making sure that all stakeholders are involved regarding features or changes in the product before any green light is given to execute. It happened that a green light was given, mockups were created based on that context and the engineering team added the feature. Only for that to get pushed back because a stakeholder that wasn't involved in the discussion saw the final result on Slack chat.</p>\n</li>\n</ul>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"transparency\">Transparency<a href=\"https://didierlopes.com/blog/implement-feedback-loops-everywhere-you-can#transparency\" class=\"hash-link\" aria-label=\"Direct link to Transparency\" title=\"Direct link to Transparency\">​</a></h3>\n<ul>\n<li>\n<p>More transparency when deals are closed - e.g. what are they interested in, how many seats, what do they do on a day-to-day basis</p>\n</li>\n<li>\n<p>When mentioning increased transparency, the vast majority of people think that our level of transparency is very high.</p>\n</li>\n<li>\n<p>A common answer: \"If I have any questions I know can just DM you and you will answer\"</p>\n</li>\n<li>\n<p>Add a Q&amp;A at the end of the status update where everyone can put questions to be answered</p>\n</li>\n<li>\n<p>A common answer: \"I don't like when someone leaves out of a sudden\". Unfortunately, we can't do anything here. We've also asked for feedback on what we could do better, but people understood that there's not much we can do. This is a conversation between the person and the manager and it's unfair for the person being let go if we share their personal information. There's a PIP and that means that before everyone leaves the company they are in 3-4 weeks PIP, where expectations are set clearly and their continuity depends on their output.</p>\n</li>\n<li>\n<p>People appreciate feedback a lot, regardless of if it's positive or not. It's the best way for them to improve.</p>\n</li>\n</ul>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"thoughts\">Thoughts<a href=\"https://didierlopes.com/blog/implement-feedback-loops-everywhere-you-can#thoughts\" class=\"hash-link\" aria-label=\"Direct link to Thoughts\" title=\"Direct link to Thoughts\">​</a></h3>\n<p>I think, at an early stage, everyone should do this. And maybe even at a later stage but in each subset of the org.</p>\n<p>One of the reasons I think this worked so well is that for the first 20 minutes, you are asking the exact same questions to everyone and so that allows you to get answers that you can compare across the board.</p>\n<p>Then, once those 20 minutes are over, the team member feels that they have already been so transparent that they openly ask questions that they are curious about.</p>\n<p>The final result was a presentation with all the combined learnings and actionable.</p>\n<p><strong>What do you think?</strong></p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/implement-feedback-loops-everywhere-you-can",
            "title": "Implement feedback loops EVERYWHERE you can",
            "summary": "Maximizing team transparency through focused feedback sessions.",
            "date_modified": "2024-10-25T00:00:00.000Z",
            "tags": [
                "openbb",
                "management",
                "leadership",
                "feedback",
                "transparency",
                "culture",
                "remote-work"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/openbb-mobile-app-coming-soon",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2024-10-05-openbb-mobile-app-coming-soon.webp\"></p>\n<p>How we built a mobile app, in 1 evening, with 1 engineer.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>Let's start with a bit of background to this story. 📖</p>\n<p>Back in September 2021, our first full-time team member was <a href=\"https://x.com/josedonato__?utm_source=didierlopes.beehiiv.com&amp;utm_medium=referral&amp;utm_campaign=openbb-mobile-app-coming-soon\" target=\"_blank\" rel=\"noopener noreferrer\">Jose Donato</a>. He started full-time, even before I did (due to my 3 months notice period in Europe, yikes).</p>\n<p>We met through Reddit, only to discover that we are both Portuguese and our hometowns aren't far from each other.</p>\n<p>I've learned more from him about web development than from any YouTube, tutorial or book - combined.</p>\n<p>One of the topics he was very passionate about, was the concept of Progressive Web Apps (PWAs). So much so, that he talked about it in his thesis (<a href=\"https://jose-donato.deno.dev/master_thesis.pdf?utm_source=didierlopes.beehiiv.com&amp;utm_medium=referral&amp;utm_campaign=openbb-mobile-app-coming-soon\" target=\"_blank\" rel=\"noopener noreferrer\">2.2 native applications</a>).</p>\n<p>I had never heard of it before, but the concept intrigued me. Why wouldn't more companies do that?</p>\n<p>Jose is currently writing a post about it, you can subscribe to the <a href=\"https://openbb.co/newsletter?utm_source=didierlopes.beehiiv.com&amp;utm_medium=referral&amp;utm_campaign=openbb-mobile-app-coming-soon\" target=\"_blank\" rel=\"noopener noreferrer\">company newsletter</a> to keep an eye out for it.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"mobile-compatibility\">Mobile compatibility<a href=\"https://didierlopes.com/blog/openbb-mobile-app-coming-soon#mobile-compatibility\" class=\"hash-link\" aria-label=\"Direct link to Mobile compatibility\" title=\"Direct link to Mobile compatibility\">​</a></h2>\n<p>Fast forward to September 3rd, 2024. 🏃‍♂️</p>\n<p>We are 1 week away from one of the biggest launches in the company. Earlier surprise for my subscribers, but we are about to announce a free version of our enterprise product.</p>\n<p>A web app that allows users to bring any type of data and have access to an agent to interact with all these different datasets to extract patterns, trends and insights.</p>\n<p>This web app has been built over 2 years and all workflows, tests, and iterations have been done for desktop usage.</p>\n<p>Jose sent me a video of a mobile version somewhat polished. It had the same UX as the terminal, but it rendered nicely on mobile.</p>\n<p align=\"center\"><img width=\"900\" src=\"https://didierlopes.com/blog/2024-10-05-openbb-mobile-app-coming-soon_2.webp\"></p>\n<p>Given that we were aiming at adoption, he believed it was important for users to be able to access the terminal through their phones on the web.</p>\n<p>And so over 2 weeks, he spent no more than 3h polishing the mobile version.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"mobile-ux\">Mobile UX<a href=\"https://didierlopes.com/blog/openbb-mobile-app-coming-soon#mobile-ux\" class=\"hash-link\" aria-label=\"Direct link to Mobile UX\" title=\"Direct link to Mobile UX\">​</a></h2>\n<p>On the 23rd of September, I pinged <a href=\"https://www.linkedin.com/in/ana-rita-soares-48b247152/?utm_source=didierlopes.beehiiv.com&amp;utm_medium=referral&amp;utm_campaign=openbb-mobile-app-coming-soon\" target=\"_blank\" rel=\"noopener noreferrer\">Rita Soares</a> - our lead UI/UX.</p>\n<p>I had been thinking about mobile user experience and wasn't happy that we just adapted the interface to work with mobile. But, mobile represents a completely different paradigm on how we use a product. The screen space, the speed at which you can type, not necessarily used for work, more distractions, etc...</p>\n<p>So, I asked Rita to create a few mobile mockups for me - the idea was to improve the UX to make the copilot shine. I.e. more front and center and have the data visualization pushed more to the background.</p>\n<p>That same evening, she shared these mockups with me:</p>\n<p align=\"center\"><img width=\"900\" src=\"https://didierlopes.com/blog/2024-10-05-openbb-mobile-app-coming-soon_3.webp\"></p>\n<p>I promptly shared in a group with her and Jose - this was 7:35 pm my time, which would be 0:35 am their time.</p>\n<p align=\"center\"><img width=\"900\" src=\"https://didierlopes.com/blog/2024-10-05-openbb-mobile-app-coming-soon_4.webp\"></p>\n<p>In less than 24 hours the bulk of the mockups had been implemented.</p>\n<p align=\"center\"><img width=\"900\" src=\"https://didierlopes.com/blog/2024-10-05-openbb-mobile-app-coming-soon_5.webp\"></p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"progressive-web-apps-pwas\">Progressive Web Apps (PWAs)<a href=\"https://didierlopes.com/blog/openbb-mobile-app-coming-soon#progressive-web-apps-pwas\" class=\"hash-link\" aria-label=\"Direct link to Progressive Web Apps (PWAs)\" title=\"Direct link to Progressive Web Apps (PWAs)\">​</a></h3>\n<p>On that same day, after Jose shared the bulk of mockups implemented.</p>\n<p>I sent him this message at 8:55 pm EST (1:55 am Portugal time for Jose).</p>\n<p align=\"center\"><img width=\"900\" src=\"https://didierlopes.com/blog/2024-10-05-openbb-mobile-app-coming-soon_7.webp\"></p>\n<p>To which he replied:</p>\n<p align=\"center\"><img width=\"900\" src=\"https://didierlopes.com/blog/2024-10-05-openbb-mobile-app-coming-soon_8.webp\"></p>\n<p>I was right, it didn't take him 30s. But it didn't take him much longer (15 minutes).</p>\n<p align=\"center\"><img width=\"900\" src=\"https://didierlopes.com/blog/2024-10-05-openbb-mobile-app-coming-soon_9.webp\"></p>\n<p>15 minutes to have OpenBB as an application on my phone.</p>\n<p>I was mind-blown.</p>\n<p>We iterated on it for an additional 1h30m together, until we had something we would be proud to share with the team the following day.</p>\n<p align=\"center\"><img width=\"300\" src=\"https://didierlopes.com/blog/2024-10-05-openbb-mobile-app-coming-soon_10.webp\"></p>\n<p>We still had to iterate on a few more areas and involve more people from the team. But the bulk of the mobile app was done.</p>\n<p>In pretty much 1 evening.</p>\n<p>With 1 person.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"conclusion\">Conclusion<a href=\"https://didierlopes.com/blog/openbb-mobile-app-coming-soon#conclusion\" class=\"hash-link\" aria-label=\"Direct link to Conclusion\" title=\"Direct link to Conclusion\">​</a></h3>\n<p>I could tell you that this doesn't happen often, but it does.</p>\n<p>Small, highly motivated teams (or individuals like Jose) with a strong initiative and a drive to make a difference, can have a tremendous impact on the company.</p>\n<p>I hope this post inspires more builders to share behind the scenes on how great products/features are built and how serendipity can play a role in it.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/openbb-mobile-app-coming-soon",
            "title": "OpenBB Mobile App - Coming soon",
            "summary": "How we built a mobile app, in 1 evening, with 1 engineer.",
            "date_modified": "2024-10-05T00:00:00.000Z",
            "tags": [
                "openbb",
                "mobile-app",
                "pwa",
                "web-development",
                "ux",
                "engineering",
                "startup-culture",
                "rapid-prototyping"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/chatgpt-and-the-future-of-ai-in-finance",
            "content_html": "<p align=\"center\"><img width=\"900\" src=\"https://didierlopes.com/blog/2024-09-21-chatgpt-and-the-future-of-ai-in-finance.webp\"></p>\n<p>I took the stage at the Cornell Quant Conference alongside Yu Yu (BlackRock) Tony Berkman (Two Sigma), and Samson Qian (Citadel), to discuss ChatGPT &amp; The Future of AI in Finance.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>Last week, I participated in a panel at the Cornell Financial Engineering Manhattan Conference. The topic of the panel was 'ChatGPT &amp; The Future of AI in Finance.'</p>\n<p>The other panelists were:</p>\n<ul>\n<li><strong>Yu Yu</strong>, Director of Data Science - BlackRock</li>\n<li><strong>Tony Berkman</strong>, Managing Director - Two Sigma</li>\n<li><strong>Samson Qian</strong>, Trader - Citadel</li>\n</ul>\n<p>After the discussion, several people reached out, mentioning it was one of their favorite panels of the day.</p>\n<p>Since this wasn't recorded, I took the opportunity to write down some of the topics discussed, along with a few additional thoughts that I believe in.</p>\n<p>I will organize the following sections based on the topics discussed at the event:</p>\n<ol>\n<li>Hallucinations</li>\n<li>Agents are the future</li>\n<li>When does it make sense to fine-tune?</li>\n<li>Compliance and Data security</li>\n</ol>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"1-hallucinations\">1. Hallucinations<a href=\"https://didierlopes.com/blog/chatgpt-and-the-future-of-ai-in-finance#1-hallucinations\" class=\"hash-link\" aria-label=\"Direct link to 1. Hallucinations\" title=\"Direct link to 1. Hallucinations\">​</a></h2>\n<p>When talking about the topic of hallucinations, I have a <a href=\"https://x.com/didier_lopes/status/1675630822093918209\" target=\"_blank\" rel=\"noopener noreferrer\">quote</a> that I love from Marc Andreesen:</p>\n<blockquote>\n<p>\"Hallucination is what we call when we don't like it. Creativity is what we call it when we do like it.\"</p>\n</blockquote>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"confident-hallucinations\">Confident hallucinations<a href=\"https://didierlopes.com/blog/chatgpt-and-the-future-of-ai-in-finance#confident-hallucinations\" class=\"hash-link\" aria-label=\"Direct link to Confident hallucinations\" title=\"Direct link to Confident hallucinations\">​</a></h3>\n<p>The fundamental issue with hallucinations is the fact that the model hallucinates with confidence.</p>\n<p>Imagine asking two different friends: \"Do you know where location X is?\"</p>\n<p><strong>Friend A</strong>: It's there.</p>\n<p><strong>Friend B</strong>: Hmm, I'm not really sure. If I had to guess, I'd say there, but I'm not 100% certain.</p>\n<p>If both gave wrong directions, you would consider <strong>Friend A</strong> a liar, but not Friend B. This is because <strong>Friend B</strong> lacked confidence in their answer, they were trying to help but highlighted that they weren't sure about it.</p>\n<p>The problem with current LLMs is that they are, for the most part, like <strong>Friend A</strong>. They say wrong things with certainty.</p>\n<p>Hallucinations would be less problematic if the default behavior were more like the answer on the right, when the LLM is not 100% confident.</p>\n<div class=\"flex justify-center items-center\"><img width=\"350\" src=\"https://didierlopes.com/blog/2024-09-21-chatgpt-and-the-future-of-ai-in-finance_1.webp\" style=\"margin-right:10px\"><img width=\"350\" src=\"https://didierlopes.com/blog/2024-09-21-chatgpt-and-the-future-of-ai-in-finance_2.webp\"></div>\n<br>\n<p>The problem with confident hallucinations is that, similar to why everyone dislikes liars, it leads to a lack of trust. So users begin to put everything that is output by an LLM under a microscope - even if what the model says is accurate.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"how-to-avoid-hallucinations\">How to avoid hallucinations<a href=\"https://didierlopes.com/blog/chatgpt-and-the-future-of-ai-in-finance#how-to-avoid-hallucinations\" class=\"hash-link\" aria-label=\"Direct link to How to avoid hallucinations\" title=\"Direct link to How to avoid hallucinations\">​</a></h3>\n<p>There are ways to address this and one of the key approaches we are extremely strong about at OpenBB is always tapping into information that is available.</p>\n<p>When a user asks a question that requires financial data, the OpenBB Copilot always searches for that data on OpenBB (either through data we make available or through private data that customers bring).</p>\n<p>The Copilot will only answer the question if that data exists. This allows the model to cite the data used in its response, so the user can double-check.</p>\n<p>This is how it looks.</p>\n<p align=\"center\"><img width=\"900\" src=\"https://didierlopes.com/blog/2024-09-21-chatgpt-and-the-future-of-ai-in-finance_3.webp\"></p>\n<p>While I've heard a few vendors promising 100% accuracy, this is simply not true.</p>\n<p>We are at a stage where technology is not even yet at the 'trust but verify' level.</p>\n<p>So instead of hallucinating with confidence, when data is unavailable, we prompt the model to return that there was no real-time information accessible to answer the query.</p>\n<p align=\"center\"><img width=\"900\" src=\"https://didierlopes.com/blog/2024-09-21-chatgpt-and-the-future-of-ai-in-finance_4.webp\"></p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"function-calling-to-increase-accuracy\">Function calling to increase accuracy<a href=\"https://didierlopes.com/blog/chatgpt-and-the-future-of-ai-in-finance#function-calling-to-increase-accuracy\" class=\"hash-link\" aria-label=\"Direct link to Function calling to increase accuracy\" title=\"Direct link to Function calling to increase accuracy\">​</a></h3>\n<p>One thing we found that significantly reduces hallucinations is enabling our agent, OpenBB Copilot, to have access to all the API backends that users have through OpenBB or those they've added themselves.</p>\n<p>Here's the sequence of actions that happen:</p>\n<ol>\n<li>The user asks the OpenBB Copilot a question.</li>\n<li>The prompt is converted into embeddings.</li>\n<li>We compare that embedding with all the ones that we have on an OpenBB vector store which contains widget signatures - name, description, category, subcategory and source.</li>\n<li>We retrieve the widgets with the highest similarity.</li>\n<li>The Copilot then decides which widget to use based on the prompt.</li>\n<li>Then Copilot also decides what parameters to use when calling that API</li>\n</ol>\n<br>\n<p>This leads to less hallucination because the LLM isn't outputting tokens based on a prompt and its internal weights. Instead, it's using its internal weights, the prompt, and a function call.</p>\n<p>Assuming the function call succeeds - with correct widget retrieval and parameters - the data becomes available for the Copilot to use, which leads to higher accuracy.</p>\n<p>Note: This still means that Copilot needs to use the correct widget and the correct parameter, but there's a <strong>higher likelihood of success</strong> because if it isn't, the API call will fail, prompting the LLM to try again.</p>\n<p>Here's how it works behind the scenes, the OpenBB Copilot highlights its step-by-step reasoning so users can understand its thought process. Transparency is key.</p>\n<p align=\"center\"><img width=\"900\" src=\"https://didierlopes.com/blog/2024-09-21-chatgpt-and-the-future-of-ai-in-finance_5.webp\"></p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"workflows-to-avoid-hallucinations\">Workflows to avoid hallucinations<a href=\"https://didierlopes.com/blog/chatgpt-and-the-future-of-ai-in-finance#workflows-to-avoid-hallucinations\" class=\"hash-link\" aria-label=\"Direct link to Workflows to avoid hallucinations\" title=\"Direct link to Workflows to avoid hallucinations\">​</a></h3>\n<p>In order to reduce the number of hallucinations, there are two things that can be done.</p>\n<h4 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"enable-users-to-quickly-detect-whether-a-hallucination-has-occurred\">Enable users to quickly detect whether a hallucination has occurred<a href=\"https://didierlopes.com/blog/chatgpt-and-the-future-of-ai-in-finance#enable-users-to-quickly-detect-whether-a-hallucination-has-occurred\" class=\"hash-link\" aria-label=\"Direct link to Enable users to quickly detect whether a hallucination has occurred\" title=\"Direct link to Enable users to quickly detect whether a hallucination has occurred\">​</a></h4>\n<p>For instance, if a user utilizes the following prompt on the OpenBB Copilot:</p>\n<blockquote>\n<p><em>Using the earnings transcript, create a table with columns: financial metric, value, sentence in the earnings where it was extracted from. Double check whether the information you are using is correct.</em></p>\n</blockquote>\n<br>\n<p>They get the \"<em>Sentence Extracted From</em>\" column, which they can copy and paste into a search field added at the top of the Earnings Transcript widget. This enable users to quickly validate the numbers that have been found.</p>\n<p>See example below,</p>\n<p align=\"center\"><img width=\"900\" src=\"https://didierlopes.com/blog/2024-09-21-chatgpt-and-the-future-of-ai-in-finance_6.webp\"></p>\n<h4 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"add-deterministic-processes-to-check-for-hallucinations\">Add deterministic processes to check for hallucinations<a href=\"https://didierlopes.com/blog/chatgpt-and-the-future-of-ai-in-finance#add-deterministic-processes-to-check-for-hallucinations\" class=\"hash-link\" aria-label=\"Direct link to Add deterministic processes to check for hallucinations\" title=\"Direct link to Add deterministic processes to check for hallucinations\">​</a></h4>\n<p>For example, let's say the user prompt involves a data retrieval task.</p>\n<p>We can run a deterministic process to check whether the retrieved values exist or not. Sure this won't be 100% accurate because the numbers could be flagged by referring to another thing, BUT it's all about improving the overall accuracy of Copilot.</p>\n<p>Ultimately, whatever can be done to improve the Copilot's accuracy should be done.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"2-agents-are-the-future\">2. Agents are the future<a href=\"https://didierlopes.com/blog/chatgpt-and-the-future-of-ai-in-finance#2-agents-are-the-future\" class=\"hash-link\" aria-label=\"Direct link to 2. Agents are the future\" title=\"Direct link to 2. Agents are the future\">​</a></h2>\n<p>When we think about how humans operate, we recognize that the brain coordinates all the actions of our body and our thought processes. This is similar to how agents work.</p>\n<p>If I'm playing soccer, the muscles I use are different from those I would use if I were boxing. If I'm programming, the parts of my brain I use differ from those I would use when listening to music.</p>\n<p>However, it's not as simple as \"activity A requires legs\". Most of your body and mind are always involved, but at different times and in different capacities. And what dictates that are external factors.</p>\n<p>For instance, if I am playing soccer as a winger and my team is attacking, I will likely be using both legs to run forward and a lot of mental energy to decide where to position myself on the field.</p>\n<p>And that will change a lot based on where the ball is. If the ball is on the opposite side, I'll likely run less and stay more in the middle to be ready for a counterattack. If the ball is in the middle, I'll probably be running at full speed to create space. If the ball is close to me I have to worry more about controlling it and understand what I can do with it next.</p>\n<p>The environment affects my plan to carry out an action where I want to have a successful outcome.</p>\n<p><strong>This is how agents work.</strong></p>\n<p>Agents aren't just about a single LLM performing well, but about a full workflow that interacts with multiple language models, function calls, or any other process to carry an action.</p>\n<p>At the core, the biggest advantage of an agent over a LLM is that an agent has a full feedback loop. It understands the impact of the LLM output and can use that data in the next step of the process. Whereas a single LLM API call returns its best output but won't know how that affected the external environment.</p>\n<p>This is why, at OpenBB, we believe in compound AI systems.</p>\n<p>And apparently, <a href=\"https://finance.yahoo.com/news/sequoia-sees-bigger-money-ai-203655254.html?guccounter=1\" target=\"_blank\" rel=\"noopener noreferrer\">so does Sequoia</a>.</p>\n<p align=\"center\"><img width=\"300\" src=\"https://didierlopes.com/blog/2024-09-21-chatgpt-and-the-future-of-ai-in-finance_7.webp\"></p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"the-strawberry-issue-will-be-solved\">The \"Strawberry\" issue will be solved<a href=\"https://didierlopes.com/blog/chatgpt-and-the-future-of-ai-in-finance#the-strawberry-issue-will-be-solved\" class=\"hash-link\" aria-label=\"Direct link to The &quot;Strawberry&quot; issue will be solved\" title=\"Direct link to The &quot;Strawberry&quot; issue will be solved\">​</a></h3>\n<p>A panelist commented on stage that LLMs can't even count how many R's are in the word \"Strawberry\".</p>\n<p>This <a href=\"https://x.com/MwangoCapital/status/1828857579860095428\" target=\"_blank\" rel=\"noopener noreferrer\">tweet</a> offers a good explanation of why this happens — it turns out it's due to the tokenizer, and it can be solved. In fact, it's solved by simply ensuring that the model takes each letter as a token. See below,</p>\n<div class=\"flex justify-center items-center\"><img width=\"300\" src=\"https://didierlopes.com/blog/2024-09-21-chatgpt-and-the-future-of-ai-in-finance_8.webp\" style=\"margin-right:10px\"><img width=\"300\" src=\"https://didierlopes.com/blog/2024-09-21-chatgpt-and-the-future-of-ai-in-finance_9.webp\"></div>\n<br>\n<p>This means that the model's output can be improved by doing extra work at the input level.</p>\n<p>Data cleaning and pre-processing strikes again? 😃</p>\n<p>Interestingly, a few days ago, <a href=\"https://openai.com/o1/\" target=\"_blank\" rel=\"noopener noreferrer\">OpenAI announced OpenAI o1</a>. Which is basically GPT-4o with Chain-of-Thought (COT). This means that this model is a \"wannabe agent\".</p>\n<p>It takes in a prompt from the user and decomposes it in natural steps to solve it. Then at each step, it takes the output of the model from the previous step and predicts the next token. It turns out that this improves accuracy substantially.</p>\n<p>However, it still doesn't have access to external data. And that is why I call it a \"wannabe agent\".</p>\n<p>I love how Jeremiah put it in this <a href=\"https://x.com/jlowin/status/1834722014839418962\" target=\"_blank\" rel=\"noopener noreferrer\">tweet</a>:</p>\n<blockquote>\n<p>(...) Agents are also characterized by iterative behavior. But there's a key difference: while models like o1 iterate internally to refine their reasoning, agents engage in iterative interactions with the external world. They perceive the environment, take actions, observe the outcomes (or side effects) and adjust accordingly. This recursive process enables agents to handle tasks that require adaptability and responsiveness to real-world changes. (...)</p>\n</blockquote>\n<br>\n<p>So, o1's model isn't an agent - but it can solve this problem. The reason is that it applies its own data cleaning/pre-processing step on its own, and doesn't rely on external factors.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"small-language-models\">Small Language Models<a href=\"https://didierlopes.com/blog/chatgpt-and-the-future-of-ai-in-finance#small-language-models\" class=\"hash-link\" aria-label=\"Direct link to Small Language Models\" title=\"Direct link to Small Language Models\">​</a></h3>\n<p>Once agents work, Small Language Models (SLM) will be much more viable for very specific use cases.</p>\n<p>In logical terms, a Large Language Model is a model with weights.</p>\n<p>Large means that it has a lot of them. But what tends to happen is LLMs need to be very big because they want these models to be really good at everything. The problem is that if you want the exact same model to be good at discussing soccer, programming, and speaking Portuguese, its weights are updated using these drastically different datasets. Now the premise is that the more weights there are, the less each weight will be affected by data from completely different domains.</p>\n<p>What a big LLM like GPT-4o is doing is trying to build a single Jarvis that knows about everything. Whereas we could have an SLM that does something extremely well and just focus on that, e.g. translating from English to Portuguese. The benefit of an SLM is that inference is likely faster, can be hosted on devices, and, in theory, it's better on a topic because it's been less \"contaminated\" during training by data that doesn't relate to the task at hand.</p>\n<p>Imagine that a firm decides to use an SLM trained to retrieve data from SEC filings quickly and at scale. Or, we could train our own SLM to understand user intent and interact directly with the OpenBB Terminal interface.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"large-language-models-as-orchestrator\">Large Language Models as orchestrator<a href=\"https://didierlopes.com/blog/chatgpt-and-the-future-of-ai-in-finance#large-language-models-as-orchestrator\" class=\"hash-link\" aria-label=\"Direct link to Large Language Models as orchestrator\" title=\"Direct link to Large Language Models as orchestrator\">​</a></h3>\n<p>In my opinion, the best LLM in each category will win. And the second and third won't matter. It's a winner-takes-all kind of market. Unless in specific verticals such as inference time or open weights (e.g. for data security; more on this later).</p>\n<p>The best example of this is OpenAI vs Anthropic.</p>\n<p>I had been using OpenAI's GPT-4 for coding for several months. After trying Anthropic's Sonnet 3.5 for coding, I never went back to OpenAI.</p>\n<p align=\"center\"><img width=\"400\" src=\"https://didierlopes.com/blog/2024-09-21-chatgpt-and-the-future-of-ai-in-finance_10.webp\"></p>\n<p>The market share for the best LLM will be gigantic. That's why <a href=\"https://www.bloomberg.com/news/articles/2024-09-11/openai-fundraising-set-to-vault-startup's-value-to-150-billion\" target=\"_blank\" rel=\"noopener noreferrer\">OpenAI is looking to raise at a $150 billion valuation</a>. While the valuation reflects the market size, the amount that will be raised represents the capital needed to reach that valuation. This is why only a few players will be able to compete at that level.</p>\n<p>In an \"agentic future\", I believe the best LLM will serve as the core \"brain\" - the main LLM that routes all prompts and decides what happens next.</p>\n<p>And who wouldn't want the smartest model controlling the actions with a list of models, functions and data at its disposal?</p>\n<p>I know I would.</p>\n<p>That's also why, when discussing OpenBB Copilot, we don't rely on a single foundational model. Instead, we use the models that are best suited for each specific task.</p>\n<p>For instance, OpenAI o1 can be the brains, but when a user uses @web it triggers the Perplexity model, and when they upload an image, we have Anthropic's Haiku. Or maybe if they want to do intraday trading, we use Llama 3.1 through Groq for fast inference.</p>\n<p>You get the idea.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"3-when-does-it-make-sense-to-fine-tune\">3. When does it make sense to fine-tune<a href=\"https://didierlopes.com/blog/chatgpt-and-the-future-of-ai-in-finance#3-when-does-it-make-sense-to-fine-tune\" class=\"hash-link\" aria-label=\"Direct link to 3. When does it make sense to fine-tune\" title=\"Direct link to 3. When does it make sense to fine-tune\">​</a></h2>\n<p>A good comment was made on the panel: \"<em>it's expensive to spend time fine-tuning a new model, just for that entire work to be 'eradicated' by a new model that has a higher performance in that specific domain than the model has been fine-tuned</em>\".</p>\n<p>In my opinion, this happens because the timing isn't right yet. We are still unlocking remarkable achievements through each new model release. Although there is a massive bump in terms of capability between these releases, I wouldn't recommend that a firm fine-tune its own models at this stage.</p>\n<p>However, at some point, whether due to a lack of data to train or architecture needing to be reinvented, improvements in LLM performance won't be substantial - they may not even be noticeable. This is when the fine-tuning technique becomes relevant because at this stage you are trying to repurpose everything the model has towards a specific vertical / use-case - and at that vertical/use-case that model will be better than the following one.</p>\n<p>Then after some new models come out, you may consider reapplying fine-tuning to that model, but this would likely be years later, not weeks or months. So, the ROI can be quite high. Particularly when you are trying to win in your specific market.</p>\n<p>This is how I see it working in my head:</p>\n<p align=\"center\"><img width=\"900\" src=\"https://didierlopes.com/blog/2024-09-21-chatgpt-and-the-future-of-ai-in-finance_11.webp\"></p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"4-compliance-and-data-security\">4. Compliance and Data security<a href=\"https://didierlopes.com/blog/chatgpt-and-the-future-of-ai-in-finance#4-compliance-and-data-security\" class=\"hash-link\" aria-label=\"Direct link to 4. Compliance and Data security\" title=\"Direct link to 4. Compliance and Data security\">​</a></h2>\n<p>Another question I received was about compliance and data security.</p>\n<p>Recently, during a discussion with one of the largest hedge funds in the world, we were asked about the entire workflow of the data when our AI Copilot has access to it.</p>\n<p>Their main concern was ensuring that no data was being shared with third-party vendors like OpenAI. For such firms, their data is their alpha, and keeping it within their network is paramount.</p>\n<p>Crypto enthusiasts often say, \"Not your keys, not your coins\" to emphasize the importance of storing assets in a cold wallet rather than leaving them on an exchange that might implode (looking at you, FTX). The same principle applies here: \"Not your weights, not your data\".</p>\n<p>When you send information to a large foundation model provider like OpenAI, your data enters their ecosystem, and you have to trust they'll honor the terms of your contract.</p>\n<p>A more secure approach is to host an open-source model locally within your firm, ensuring that sensitive data remains entirely within your infrastructure and network.</p>\n<p>Although open-source models aren't yet as powerful as closed-source ones, they are catching up quickly. If you think that GPT-4o can already do a lot for you, think about how at some point there will be an open-source model that is GPT-4o equivalent. Sure, at that time closed-source models will be better, but the question is: How much better?</p>\n<p>Or better, the question is: <strong>\"How much are you willing to sacrifice in terms of data security for performance?\"</strong>.</p>\n<p>At OpenBB, we take this very seriously and have taken measures to allow enterprise customers to fully control their data.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"bring-your-own-copilot\">Bring your own copilot<a href=\"https://didierlopes.com/blog/chatgpt-and-the-future-of-ai-in-finance#bring-your-own-copilot\" class=\"hash-link\" aria-label=\"Direct link to Bring your own copilot\" title=\"Direct link to Bring your own copilot\">​</a></h3>\n<p>Enable firms to bring their own LLMs to access data within OpenBB. This means that we provide an interface for research, but also allow them to integrate their internal LLMs and interact directly with it from OpenBB.</p>\n<div class=\"flex justify-center items-center\"><img width=\"350\" src=\"https://didierlopes.com/blog/2024-09-21-chatgpt-and-the-future-of-ai-in-finance_12.webp\" style=\"margin-right:10px\"><img width=\"350\" src=\"https://didierlopes.com/blog/2024-09-21-chatgpt-and-the-future-of-ai-in-finance_13.webp\"></div>\n<br>\n<p>We believe in this idea so much, that we have open-source the architecture for firms to bring their own Copilot to OpenBB. More information is available <a href=\"https://github.com/OpenBB-finance/copilot-for-terminal-pro/\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"turn-off-ai-workflows\">Turn off AI workflows<a href=\"https://didierlopes.com/blog/chatgpt-and-the-future-of-ai-in-finance#turn-off-ai-workflows\" class=\"hash-link\" aria-label=\"Direct link to Turn off AI workflows\" title=\"Direct link to Turn off AI workflows\">​</a></h3>\n<p>We have incorporated workflows that make users' lives MUCH better. But they come at a cost: sharing data with an LLM provider.</p>\n<p>These are the features:</p>\n<ul>\n<li><strong>Widget title/description suggestion from Copilot</strong>: This sends the content of the table or note output by Copilot to an LLM provider to receive suggestions of a title and description.</li>\n</ul>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2024-09-21-chatgpt-and-the-future-of-ai-in-finance_14.webp\"></p>\n<ul>\n<li><strong>Widget title/description suggestion upon upload</strong>: It sends the content of the file that has been uploaded to an LLM provider to receive suggestions of title and description.</li>\n</ul>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2024-09-21-chatgpt-and-the-future-of-ai-in-finance_15.webp\"></p>\n<ul>\n<li><strong>Copilot chat title generation</strong>: Upon the first user prompt, the content is sent to an LLM provider to update the chat title, reflecting the nature of the conversation.</li>\n</ul>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2024-09-21-chatgpt-and-the-future-of-ai-in-finance_16.webp\"></p>\n<ul>\n<li><strong>Dashboard name generation</strong>: When renaming the dashboard, we send the title and descriptions of all widgets on that dashboard to an LLM provider, to ensure that the suggested name is relevant.</li>\n</ul>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2024-09-21-chatgpt-and-the-future-of-ai-in-finance_17.webp\"></p>\n<p>To allow firms to keep their data within their network, one of our enterprise features is the option to disable these AI workflows.</p>\n<p align=\"center\"><img width=\"900\" src=\"https://didierlopes.com/blog/2024-09-21-chatgpt-and-the-future-of-ai-in-finance_18.webp\"></p>\n<p>In the future, we could direct these AI workflows to use an LLM that our customers are running locally.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"so-in-a-nutshell-what-can-you-expect-from-openbb\">So, in a nutshell, what can you expect from OpenBB?<a href=\"https://didierlopes.com/blog/chatgpt-and-the-future-of-ai-in-finance#so-in-a-nutshell-what-can-you-expect-from-openbb\" class=\"hash-link\" aria-label=\"Direct link to So, in a nutshell, what can you expect from OpenBB?\" title=\"Direct link to So, in a nutshell, what can you expect from OpenBB?\">​</a></h2>\n<p>We are building an AI-powered research workspace.</p>\n<p>At the core it is an AI compound system, where users can bring their own data (structured, unstructured, API, custom backend, database, data warehouse, etc..) and have our (or their own copilot) access all this data seamlessly - in an interface that is customizable, flexible and enables teams to work together.</p>\n<p>If you want to learn more, e-mail me directly at <a href=\"mailto:didier.lopes@openbb.finance\" target=\"_blank\" rel=\"noopener noreferrer\">didier.lopes@openbb.finance</a></p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/chatgpt-and-the-future-of-ai-in-finance",
            "title": "ChatGPT and The Future of AI in Finance",
            "summary": "I took the stage at the Cornell Quant Conference alongside Yu Yu (BlackRock) Tony Berkman (Two Sigma), and Samson Qian (Citadel), to discuss ChatGPT & The Future of AI in Finance.",
            "date_modified": "2024-09-21T00:00:00.000Z",
            "tags": [
                "ai",
                "fintech",
                "llm",
                "agents",
                "hallucinations",
                "fine-tuning",
                "data-security",
                "openbb",
                "thought-leadership"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/why-i-love-boxing",
            "content_html": "<p align=\"center\"><img width=\"300\" src=\"https://didierlopes.com/blog/2024-09-09-why-i-love-boxing.webp\"></p>\n<p>Exploring the parallels between boxing and startup life, and how both push me beyond my comfort zone to foster personal growth, resilience, and continuous learning.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>Recently, I finished reading \"The Art of Learning\" - a really good book that I've recommend to everyone (btw, <a href=\"https://x.com/didier_lopes/status/1742748040220328189?s=20\" target=\"_blank\" rel=\"noopener noreferrer\">here</a> is a page of all the books I've read in the past few years).</p>\n<p>In it, the author Josh Waitzkin, reflects on his journey from chess champion to martial arts practicioner - and how anyone can master the art of learning.</p>\n<p align=\"center\"><img width=\"300\" src=\"https://didierlopes.com/blog/2024-09-09-why-i-love-boxing_1.webp\"></p>\n<p>It made me wonder, why at 29 years old did I decide to step into a ring with boxers who have been fighting for 10+ years? 🥊</p>\n<p>As my friend Max says, \"You don't play boxing\". So why am I doing it?</p>\n<p>Similar to setting up a startup, this isn't something that's easy to explain. The most rationale thing to do would be to go for a run outside or just go to the gym.</p>\n<p>Yet, I hop in a ring to fight.</p>\n<p>Why?</p>\n<p>For starters, there's something thrilling about stepping into the ring and knowing that you are going to get punched.</p>\n<p>You need to get comfortable with something that - by definition - it's uncomfortable.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"boxing-is-the-physical-to-what-startups-are-for-the-mind\">Boxing is the physical to what startups are for the mind<a href=\"https://didierlopes.com/blog/why-i-love-boxing#boxing-is-the-physical-to-what-startups-are-for-the-mind\" class=\"hash-link\" aria-label=\"Direct link to Boxing is the physical to what startups are for the mind\" title=\"Direct link to Boxing is the physical to what startups are for the mind\">​</a></h2>\n<p>Think about it. Most activities that people do in their spare time have a \"controlled\" level of intensity. You get progressively more tired but \"know\" it's coming - e.g. gym, swimming, tennis, running, etc.</p>\n<p>Contact sports are in general like this too, although every now and then you can get injured. Although this rate is small, and sports in general equip athletes to be protected against injuries.</p>\n<p>Boxing (and martial arts) don't work this way. You step in the ring and within the first few seconds, you may get a hook that gives you a bruise next to your eye or a uppercut that makes you stop breathing for a few seconds.</p>\n<p>My point is that with boxing, you don't know when you are going to get hurt, but you learn to be comfortable with it and over time your body gets used to that level of pain - so it will take even more to make you uncomfortable.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2024-09-09-why-i-love-boxing_2.webp\"></p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"first-sparring-session\">First sparring session<a href=\"https://didierlopes.com/blog/why-i-love-boxing#first-sparring-session\" class=\"hash-link\" aria-label=\"Direct link to First sparring session\" title=\"Direct link to First sparring session\">​</a></h2>\n<p>I still remember my first sparring session, I got hit on the nose and had tears coming out of my eyes from it. My nose hurt for 3 days in a row. It doesn't matter how many times the coach told me to keep my hands up, nothing taught me quicker than that cross on my nose.</p>\n<p>For the remainder of the fight, I was mostly protecting myself and keeping my distance. I was \"humbled\" by the other fighter, and was pushed to outside my comfort zone.</p>\n<p>This is not so much different from startup life where mentally you have to be in uncomfortable places - for me this is the equivalent to speaking on a stage. For an introvert like myself, that was something that was hard to overcome. Although I am still not comfortable on a stage, I am much more comfortable than I used to be.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2024-09-09-why-i-love-boxing_3.webp\"></p><p style=\"font-size:0.8em\">Presenting at CIBC a few weeks ago at New York AI meetup</p><p></p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"next-sparring-sessions\">Next sparring sessions<a href=\"https://didierlopes.com/blog/why-i-love-boxing#next-sparring-sessions\" class=\"hash-link\" aria-label=\"Direct link to Next sparring sessions\" title=\"Direct link to Next sparring sessions\">​</a></h2>\n<p>Currently when I step in a ring I have mixed feelings, I'm somewhat anxious but also excited about it.</p>\n<p>It's weird.</p>\n<p>I mean, I know full well that I'm going against folks who've been in a ring since they were young - and I also know full well that I'm going to get hit much more than I will hit.</p>\n<p><strong>However</strong>, there's something exciting (poetic maybe?) about knowing that each time I step into the ring again, I will be able to land more punches, avoid more hits and be better mentally.</p>\n<p>Learning is the nature of the game.</p>\n<p>And the only failure is to not take any lessons from each fight.</p>\n<p>This is the same for startups. I like what Bezos has to say on the topic, about <a href=\"https://www.youtube.com/shorts/HmYj-UDT8jM\" target=\"_blank\" rel=\"noopener noreferrer\">pushing Amazon to embrace failure</a>.</p>\n<p align=\"center\"><img width=\"300\" src=\"https://didierlopes.com/blog/2024-09-09-why-i-love-boxing_4.webp\"></p><p style=\"font-size:0.8em\">This picture was what convinced me to buy my own head gear</p><p></p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"so-why-do-i-love-boxing\">So, why do I love boxing?<a href=\"https://didierlopes.com/blog/why-i-love-boxing#so-why-do-i-love-boxing\" class=\"hash-link\" aria-label=\"Direct link to So, why do I love boxing?\" title=\"Direct link to So, why do I love boxing?\">​</a></h2>\n<p>I think ultimately, the reason why I love boxing is the same as why I love startups.</p>\n<p>Startups push me everyday to be the best that I can be in so many different areas, there isn't a role that - for me - is as stimulating mentally as being a startup founder.</p>\n<p>There are 100 different initiatives ongoing at all times, you have a team of composed of human beings (by nature, highly complex with different backgrounds and life experiences), you have startups trying to disrupt your business, you have well established incumbents, etc..</p>\n<p>Boxing is the same... but at the physical level.</p>\n<p>I step in the ring and need to be the best I can in multiple verticals - it isn't enough to be the best in one.</p>\n<p>I need to have a faster reaction to avoid punches, be light on my feet to surprise an opponent, land the combos where I put most of my energy in, trade-off balance between combos and stamina, and obviously all the mental side that comes from it too - which turns out is quite a lot.</p>\n<p>Ultimately, as cheesy as it sounds, being a startup founder and doing boxing make me feel alive.</p>\n<p align=\"center\"><img width=\"300\" src=\"https://didierlopes.com/blog/2024-09-09-why-i-love-boxing_5.webp\"></p><p style=\"font-size:0.8em\">Taking my father-in-law for a class</p><p></p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/why-i-love-boxing",
            "title": "Why I love boxing",
            "summary": "Exploring the parallels between boxing and startup life, and how both push me beyond my comfort zone to foster personal growth, resilience, and continuous learning.",
            "date_modified": "2024-09-09T00:00:00.000Z",
            "tags": [
                "boxing",
                "startup",
                "personal-growth",
                "learning",
                "resilience",
                "comfort-zone",
                "mindset",
                "philosophy",
                "life-lessons"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/what-i-learned-in-3-years-at-openb",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2024-08-20-what-i-learned-in-3-years-at-openb.webp\"></p>\n<p>The OpenBB journey started officially 3 years ago.</p>\n<p>So I want to celebrate it by sharing 36 lessons I learned over the past 36 months as a founder and CEO of a fintech company.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>The OpenBB journey started officially 3 years ago.</p>\n<p>So I want to celebrate it by sharing 36 lessons I learned over the past 36 months as a founder and CEO of a fintech company.</p>\n<ol>\n<li>\n<p>Be curious.</p>\n</li>\n<li>\n<p>Talk to users.</p>\n</li>\n<li>\n<p>Protect your time.</p>\n</li>\n<li>\n<p>Do the right thing.</p>\n</li>\n<li>\n<p>Culture is everything.</p>\n</li>\n<li>\n<p>Energy is contagious.</p>\n</li>\n<li>\n<p>Hire slow and fire fast.</p>\n</li>\n<li>\n<p>Write everything down.</p>\n</li>\n<li>\n<p>Reward people who care.</p>\n</li>\n<li>\n<p>Celebrate every little win.</p>\n</li>\n<li>\n<p>Work on your storytelling.</p>\n</li>\n<li>\n<p>Ship often and iterate fast.</p>\n</li>\n<li>\n<p>Listen more than you speak.</p>\n</li>\n<li>\n<p>Be comfortable with saying no.</p>\n</li>\n<li>\n<p>When in doubt, there's no doubt.</p>\n</li>\n<li>\n<p>Over communicate with the team.</p>\n</li>\n<li>\n<p>Have an inherent sense of urgency.</p>\n</li>\n<li>\n<p>Don't overthink, estimate and iterate.</p>\n</li>\n<li>\n<p>Failing is ok, not learning from it isn't.</p>\n</li>\n<li>\n<p>Measure success by impact, not effort.</p>\n</li>\n<li>\n<p>Do not run away from hard conversations.</p>\n</li>\n<li>\n<p>Having common sense is a very powerful skill.</p>\n</li>\n<li>\n<p>How you do anything is how you do everything.</p>\n</li>\n<li>\n<p>It's not because you can build it that you should.</p>\n</li>\n<li>\n<p>Seeing your vision materialize gives goosebumps.</p>\n</li>\n<li>\n<p>Be so excited in your product that users can feel it.</p>\n</li>\n<li>\n<p>Lack of focus is likely the biggest risk you face as a company.</p>\n</li>\n<li>\n<p>It turns out that there's a ton of data in your gut feeling.</p>\n</li>\n<li>\n<p>Make people accountable for both successes and failures.</p>\n</li>\n<li>\n<p>Hiring is the most important thing you will do at your company.</p>\n</li>\n<li>\n<p>Create a culture where feedback is not only welcome but expected.</p>\n</li>\n<li>\n<p>Work side-by-side with the team on things that are considered \"boring\".</p>\n</li>\n<li>\n<p>Be there for your team when they need you, they will repay you with loyalty.</p>\n</li>\n<li>\n<p>One of the worst things you can do is optimizing something that shouldn't exist.</p>\n</li>\n<li>\n<p>Vast majority of decisions are 2-way door decisions. Make a decision and move on.</p>\n</li>\n<li>\n<p>Startups are hard and fun. Working with people you like makes it less hard and more fun.</p>\n</li>\n</ol>\n<br>\n<p>In the past 3 years, we have:</p>\n<ul>\n<li>The <a href=\"https://github.com/OpenBB-finance/OpenBB\" target=\"_blank\" rel=\"noopener noreferrer\">open source repo</a> has been starred over 28,000 times and 220 contributors</li>\n<li>The OG OpenBB Terminal installer was downloaded over 150k times</li>\n<li>Refactored that application to a platform that could be pip installable</li>\n<li>Enabled users to fully <a href=\"https://youtu.be/cgeN3Ep2nEw?si=8e5en_xunWcBdKMM\" target=\"_blank\" rel=\"noopener noreferrer\">automate their research workflow in a script</a></li>\n<li>Open-sourced an <a href=\"https://github.com/OpenBB-finance/openbb-agents\" target=\"_blank\" rel=\"noopener noreferrer\">LLM-powered financial analyst agent built on top of the OpenBB platform</a></li>\n<li>Made an <a href=\"https://openbb.co/products/bot\" target=\"_blank\" rel=\"noopener noreferrer\">OpenBB Bot</a> that run over 4M commands in 20k+ servers with 50k+ users</li>\n<li>Developed an <a href=\"https://openbb.co/products/excel\" target=\"_blank\" rel=\"noopener noreferrer\">Add-in for Excel</a></li>\n<li>Grew to a team of 16</li>\n<li>Built a community of over 100k people</li>\n<li>And finally, we built the foundation of the <a href=\"https://openbb.co/products/pro\" target=\"_blank\" rel=\"noopener noreferrer\">first AI-powered financial terminal</a> - more on this very very soon.</li>\n</ul>\n<br>\n<p>Personally, during that timeline:</p>\n<ul>\n<li>I got a second dog</li>\n<li>Visited US for the first time</li>\n<li>Got married on that first visit</li>\n<li>Left London to move to the Bay area a couple weeks after</li>\n<li>Moved to NYC</li>\n<li>Started boxing regularly</li>\n</ul>\n<p>We are more locked in than ever before.</p>\n<p>Can't wait for the next 3 years. 🥂</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/what-i-learned-in-3-years-at-openb",
            "title": "What I learned in 3 Years at OpenBB",
            "summary": "The OpenBB journey started officially 3 years ago. So I want to celebrate it by sharing 36 lessons I learned over the past 36 months as a founder and CEO of a fintech company.",
            "date_modified": "2024-08-20T00:00:00.000Z",
            "tags": [
                "openbb",
                "founder-story",
                "startup",
                "leadership",
                "learnings",
                "reflection",
                "career-growth",
                "milestones",
                "life-lessons"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/why-ai-will-replace-jobs-in-finance-and-how-you-should-prepare",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2024-08-06-why-ai-will-replace-jobs-in-finance-and-how-you-should-prepare.webp\"></p>\n<p>It's not a matter of if, but a matter of when. AI will replace analysts' jobs, and we actually believe that's a good thing. In this blog post, we explain why and how you can prepare for this revolutionary change in the world of finance.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"introduction\">Introduction<a href=\"https://didierlopes.com/blog/why-ai-will-replace-jobs-in-finance-and-how-you-should-prepare#introduction\" class=\"hash-link\" aria-label=\"Direct link to Introduction\" title=\"Direct link to Introduction\">​</a></h2>\n<p>This is the current state of Quant/Finance/Investing conferences in 2024</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2024-08-06-why-ai-will-replace-jobs-in-finance-and-how-you-should-prepare_1.webp\"></p>\n<p>I've heard panels defending both sides: Yes and No.</p>\n<p>I think that people who say \"No\" don't understand how AI fundamentally works, and most people who say \"Yes\" are understating the impact it will have.</p>\n<p>Personally, a much better question is \"When will AI replace financial analysts?\" or \"How can I prepare for the shift?\"</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"history\">History<a href=\"https://didierlopes.com/blog/why-ai-will-replace-jobs-in-finance-and-how-you-should-prepare#history\" class=\"hash-link\" aria-label=\"Direct link to History\" title=\"Direct link to History\">​</a></h2>\n<p>If we look back at the automotive industry, 100 years ago - this is what a Ford factory looked like:</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2024-08-06-why-ai-will-replace-jobs-in-finance-and-how-you-should-prepare.webp\"></p>\n<p>How many of these blue-collar workers would have said that their jobs would be extinct in less than 100 years? And for the most part, they are.</p>\n<p>This is where we are today in terms of AI.</p>\n<p>Some tooling (read: AI) can help humans do their job, but it still needs to be supervised.</p>\n<p>But with enough time (for the automotive industry that was 100 years), AI will take over.</p>\n<p>This is what Tesla's Giga Berlin factory looks like today.</p>\n<div class=\"flex place-items-center justify-center items-center rounded-sm mx-auto\"><iframe src=\"https://www.youtube.com/embed/7-4yOx1CnXE?si=k-adJ_cOlXS6Ldlv\" width=\"800\" height=\"400\"></iframe></div>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"when-will-ai-replace-financial-analysts\">When will AI replace financial analysts?<a href=\"https://didierlopes.com/blog/why-ai-will-replace-jobs-in-finance-and-how-you-should-prepare#when-will-ai-replace-financial-analysts\" class=\"hash-link\" aria-label=\"Direct link to When will AI replace financial analysts?\" title=\"Direct link to When will AI replace financial analysts?\">​</a></h2>\n<p>Bill Gates famously said: \"Most people overestimate what they can achieve in a year and underestimate what they can achieve in ten years\".</p>\n<p>I've found this to be mostly true for everything tech.</p>\n<p>EXCEPT AI.</p>\n<p>This is why I'm so bullish on the category as a whole.</p>\n<p>I subscribe to a few newsletters that share daily AI updates, and it's crazy that every single day there's something big happening. Either a new model is released and open source, a new framework to do RAG or fine-tune, a new company announces they are working on foundational models, a new paper that pushes the field forward, or a new investment from a big corporation.</p>\n<p>I mean, even enterprises are rushing to jump into the AI train. Either releasing AI features to millions of users before proper testing (e.g. Gemini overview on Google and the whole Reddit answers), adding AI where it isn't really necessary (e.g. Meta AI on WhatsApp), exploring new monetization opportunities (e.g. Amazon Bedrock for fine-tuning) or risking on their values to not be left behind (e.g. Apple partnering with OpenAI — risking the security brand they worked so hard for).</p>\n<p>So, I think this will happen soon.</p>\n<p>And it's with that in mind that we have been building OpenBB.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"how-can-i-prepare-for-the-shift\">How can I prepare for the shift?<a href=\"https://didierlopes.com/blog/why-ai-will-replace-jobs-in-finance-and-how-you-should-prepare#how-can-i-prepare-for-the-shift\" class=\"hash-link\" aria-label=\"Direct link to How can I prepare for the shift?\" title=\"Direct link to How can I prepare for the shift?\">​</a></h2>\n<p>I think that the most important question that financial analysts should ask themselves is not '<strong>when</strong>' but '<strong>what can I do to prepare myself for when AI starts taking over</strong>'.</p>\n<p>There's going to be multiple stages before AI fully takes over. Here's how I envision it playing out:</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2024-08-06-why-ai-will-replace-jobs-in-finance-and-how-you-should-prepare_2.webp\"></p>\n<p>(For what it's worth, I think this is equivalent to what will happen to developers in general).</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"short-term\">Short term<a href=\"https://didierlopes.com/blog/why-ai-will-replace-jobs-in-finance-and-how-you-should-prepare#short-term\" class=\"hash-link\" aria-label=\"Direct link to Short term\" title=\"Direct link to Short term\">​</a></h3>\n<p>We are starting to enter this timeline.</p>\n<p>A timeline where analysts will use AI to augment their output.</p>\n<p>A good analyst using AI will be able to perform at a better level than a great analyst who doesn't use AI.</p>\n<p>Interestingly, a mediocre analyst will be able to increase their output but nowhere as much as a good or great analyst. This is because the AI usage will supervised and still \"driven\" by the analyst (through prompts). So mediocre analysts will not benefit as much because they will either trust too much the AI (without being able to discern its validity), not use the best prompts because they don't know what to use the AI for, or not use the output because they won't comprehend the insights that the AI is generating.</p>\n<p>During this period, the gap between mediocre and great analysts will be at an all-time high. This will expose more who is pushing their weight and who isn't.</p>\n<p>Another thing is that firms that will be hiring high-talented juniors/interns will start adding AI experience as a requirement (e.g. OpenBB experience) since they understand that they will have a higher leverage and their output will be much better. Potentially even replacing a current analyst with many years of experience that doesn't leverage AI in the day-to-day.</p>\n<p>I think there are 2 reasons for this:</p>\n<ol>\n<li>\n<p><strong>AI will allow financial analysts to have much broader mandates</strong> as they will be able to automate the process of research and screen the best companies. Instead of analyzing 20 companies per quarter, they will do 500.</p>\n</li>\n<li>\n<p><strong>AI will be able to extract trends and patterns that humans simply can't due to the amount of data necessary to process</strong>. The amount of data that financial firms use to invest is constantly on the rise, that's where they get their alpha from. Given that an analyst has a limited amount of resources, they will either have to narrow down the companies in their mandate or process less data for each.</p>\n</li>\n</ol>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"long-term\">Long term<a href=\"https://didierlopes.com/blog/why-ai-will-replace-jobs-in-finance-and-how-you-should-prepare#long-term\" class=\"hash-link\" aria-label=\"Direct link to Long term\" title=\"Direct link to Long term\">​</a></h3>\n<p>In the long term, AI will start taking the reigns.</p>\n<p>This is the equivalent of self-driving cars becoming fully autonomous.</p>\n<p>The gap between mediocre and great analysts will narrow over time because AI is doing all the heavy work.</p>\n<p>At that time, it will be very hard to distinguish the competency of mediocre and great analysts — the main indicator will be how they interpret/understand the AI model, i.e. how they can explain what led to the AI \"deciding\" to invest in companies based on hundreds of different datasets.</p>\n<p>This is why we spend hours obsessing over the UX of the <a href=\"https://openbb.co/products/pro\" target=\"_blank\" rel=\"noopener noreferrer\">OpenBB Terminal Pro</a>. We want to make sure analysts know at all times what the AI Copilot is doing and thinking. Because interpretability will be a big topic in the future.</p>\n<p>It's important to note that the best analysts will be the ones who have their jobs more secure over time. That is because provided the AI is taking the reigns, when it fully takes the reigns, the output of all analysts will be more or less the same. However, in the period before, the great analyst will have an edge because their skill is still in use and so the leverage lever is bigger.</p>\n<p>I think that when AI fully takes over analysts' jobs, the best ones will move towards opening their investment firms and focus on the human part of the job: communication.</p>\n<p>Communicating to their investors why they made their decisions, e.g. \"We have access to this dataset which others don't, and our AI model correlated that data with x, y, and z which enabled us to invest ahead of the rest of the market\". This is the \"interpretability\" of the AI that I mentioned earlier.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"what-can-you-do\">What can you do?<a href=\"https://didierlopes.com/blog/why-ai-will-replace-jobs-in-finance-and-how-you-should-prepare#what-can-you-do\" class=\"hash-link\" aria-label=\"Direct link to What can you do?\" title=\"Direct link to What can you do?\">​</a></h2>\n<p>You should still pursue a career in the space.</p>\n<p>But you should do so with AI in mind.</p>\n<p>Experiment with products out there that leverage AI to make you more efficient (you can try OpenBB for free at pro.openbb.co). You will soon realize that your output can compete with someone who is neglecting AI in their day-to-day.</p>\n<p>Being a top financial analyst is still something you should strive for since these are going to be the last to be replaced. And when they are, you will still have an edge because your role is likely to evolve into a communication/management role that explains what the AI is doing to investors. And that would be much easier if you're a top analyst in the first place - because you would understand the insights extracted from an AI copilot.</p>\n<p>What is your opinion on this topic?</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/why-ai-will-replace-jobs-in-finance-and-how-you-should-prepare",
            "title": "Why AI Will Replace Jobs in Finance and How You Should Prepare",
            "summary": "As AI continues to advance, many jobs in finance are at risk. Learn why this shift is happening and how to prepare for the future.",
            "date_modified": "2024-08-06T00:00:00.000Z",
            "tags": [
                "ai",
                "finance",
                "fintech",
                "future-of-work",
                "career-advice",
                "automation",
                "reskilling",
                "analyst"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/inspired-by-bia-how-her-fight-against-cancer-changed-my-life",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2024-08-01-inspired-by-bia-how-her-fight-against-cancer-changed-my-life.webp\"></p>\n<p>In a time when we talk about going to Mars and having AGI, cancer is still taking lives every day.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>This cause could not have been a personal one, but it is.</p>\n<p>As a young kid from a small town in Portugal, people who die from cancer are on TV and I don't know them personally.\n&nbsp;\nMy friends &amp; family are \"protected\" by an imaginary shield that I created in my head.</p>\n<p>Until they aren't.</p>\n<p>Let me go back down memory lane and talk about Beatriz.</p>\n<p>Bia was in my class in high school.</p>\n<p>We started talking here and there.</p>\n<p>Before I knew it, she was my best friend.</p>\n<p>We would talk for hours about everything and nothing - always laughing.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2024-08-01-inspired-by-bia-how-her-fight-against-cancer-changed-my-life.webp\"></p>\n<p>We would sit next to each other and professors would have a hard time with us because we liked to chit chat.</p>\n<p>So we created a new communication medium to not get caught.</p>\n<p>We would rip the side of those pages and write in very small font notes to each other.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2024-08-01-inspired-by-bia-how-her-fight-against-cancer-changed-my-life_1.webp\"></p>\n<p>We would go through multiple of these in each class.</p>\n<p>It was our thing.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2024-08-01-inspired-by-bia-how-her-fight-against-cancer-changed-my-life_2.webp\"></p>\n<p>A few months later, we had a sports class and she felt weak from her wrist.</p>\n<p>She didn't really like sports. So I remember making fun of her for trying to find an excuse to skip sports class.</p>\n<p>That would be the last time I made fun of that.</p>\n<p>She went to the hospital the day after, and to another one soon for a second opinion.</p>\n<p>She had cancer. On her back.</p>\n<p>Her floor was pulled from under her.</p>\n<p>She was 16 and while kids her age were worrying about boys and school grades, she had to fight for her life.</p>\n<p>At fucking 16.</p>\n<p>The crazy part is that the attitude she had with others was the same.</p>\n<p>She would not display any weakness throughout none of it.</p>\n<p>She was so strong. At 16.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2024-08-01-inspired-by-bia-how-her-fight-against-cancer-changed-my-life_3.webp\"></p>\n<p>One day I visited her and she had no hair because of chemotherapy.</p>\n<p>She was still the same beautiful and happy girl that I loved.</p>\n<p>Underneath it all, I don't know where she got the strength to go through it.</p>\n<p>The school adapted the classes to be livestream so that she could attend from home.</p>\n<p>Not only she wasn't gonna lose this battle but she didn't want to lose 1 year of school either.</p>\n<p>She was incredibly smart for her age. So losing a year wasn't an option for her.</p>\n<p>At the graduation she wrote me a message. She didn't have strength in her hand to write so she used her wrist to be able to write it in an iPad.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2024-08-01-inspired-by-bia-how-her-fight-against-cancer-changed-my-life_4.webp\"></p>\n<p>The translation doesn't make it justice, but it reads as:</p>\n<blockquote><p>Didier</p><br><p>It was in the middle of laughter, in the middle of playfulness.</p><br><p>It was in the middle of tantrums and misunderstandings.</p><br><p>It was in the middle of sheets of paper fallen on the floor and of pieces of paper so efficiently utilized.</p><br><p>It was like this that our friendship grew!</p><br><p>Beatriz ❤️</p></blockquote>\n<br>\n<p>Saturday morning I got a call. A common friend let me know that she passed away unexpectedly.</p>\n<p>I was still in bed. I cried for hours. I didn't want to wake up. Maybe some part of me never did.</p>\n<p>She had her entire life ahead of her.</p>\n<p>She was kind, curious and loving. She would have accomplished so much.</p>\n<p>Yet she was gone.</p>\n<p>No one deserves to lose their best friend at 17. Not like that. It wasn't fair.</p>\n<p>But that's cancer for you.</p>\n<p>Cancer doesn't care.</p>\n<p>It never did.</p>\n<p>From that moment onwards I changed my attitude towards life.</p>\n<p>I stopped doing things for the sake of doing them and always put 120%.</p>\n<p>I went from spending most of my time as a gamer and doing just enough to have good grades in high school to being the best student of my year in my BSc in Electrical and Computer Engineering, moving to London to have a distinction at Imperial College London (top 2 uni in the world) and now moving to NYC to increase chances of success for my startup.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2024-08-01-inspired-by-bia-how-her-fight-against-cancer-changed-my-life_5.webp\"></p>\n<p>I have a tattoo that says \"All her would-haves are our opportunities\" (which is from Anne Frank's house in Amsterdam) to remind me that every day I have opportunities that she didn't get to experience.</p>\n<p>But I hope that in some way, shape or form, she is.</p>\n<p>And that I make her proud.</p>\n<p>Stories like this are not as uncommon as you may think they are.</p>\n<p>It took me over 10 years to talk about how cancer took my best friend's life away.</p>\n<p>Imagine the number of people who never write about how it impacted their lives.</p>\n<p>If anything, my objective with this post is to highlight that cancer is real.</p>\n<p>In a time when we talk about going to Mars and having AGI, cancer is still taking lives every day...</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p><a href=\"https://haymakersforhope.org/\" target=\"_blank\" rel=\"noopener noreferrer\">Haymakers for Hope</a> is an organization dedicated to raising funds for cancer research and care. They organize unique events that combine athleticism with philanthropy, making a significant impact in the fight against cancer.</p>\n<p>On March 16, 2025, I will be running the NYC Half Marathon as part of the Haymakers for Hope team.</p>\n<p>Join me in this fight against cancer, for Bia and for all those whose lives have been touched by this disease.</p>\n<p>I've created a <a href=\"https://haymakersforhope.org/events/running/nyc-half-marathon-2025/runners/Didier-Lopes\" target=\"_blank\" rel=\"noopener noreferrer\">fundraising page</a> where you can support this cause.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2024-08-01-inspired-by-bia-how-her-fight-against-cancer-changed-my-life_6.webp\"></p>\n<p class=\"text-center\"><a href=\"https://haymakersforhope.org/events/running/nyc-half-marathon-2025/runners/Didier-Lopes\" class=\"inline-block px-5 py-2.5 bg-[#0088CC] text-white rounded font-bold hover:bg-[#006699] transition-colors duration-300\">Donate here</a></p>\n<p>Every donation matters. ❤️</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/inspired-by-bia-how-her-fight-against-cancer-changed-my-life",
            "title": "Inspired by Bia - How her fight against cancer changed my life",
            "summary": "In a time when we talk about going to Mars and having AGI, cancer is still taking lives every day.",
            "date_modified": "2024-08-01T00:00:00.000Z",
            "tags": [
                "personal-story",
                "grief",
                "motivation",
                "cancer-awareness",
                "charity",
                "fundraising",
                "life-lessons",
                "resilience",
                "inspiration"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/my-first-hand-experience-on-ai-impacting-education-through-perplexity-cursor-and-chatgpt",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2024-06-30-my-first-hand-experience-on-ai-impacting-education-through-perplexity-cursor-and-chatgpt.webp\"></p>\n<p>AI will change education forever. Here's how I leveraged Perplexity, Cursor and ChatGPT to teach Supervised Learning and assess coursework.</p>\n<p>The open source code is available <a href=\"https://github.com/DidierRLopes/supervised-learning\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>Recently I was invited to teach a course in Big Data and Data Analytics at Europeia University. I gave 4 hours of classes, divided into:</p>\n<ul>\n<li>Supervised Learning - Theory</li>\n<li>Supervised Learning - Practice</li>\n</ul>\n<p>And then evaluated the students coursework.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"creating-a-new-syllabus\">Creating a new syllabus<a href=\"https://didierlopes.com/blog/my-first-hand-experience-on-ai-impacting-education-through-perplexity-cursor-and-chatgpt#creating-a-new-syllabus\" class=\"hash-link\" aria-label=\"Direct link to Creating a new syllabus\" title=\"Direct link to Creating a new syllabus\">​</a></h2>\n<p>My past experience as a teacher happened during my BSc., back in 2016, where I was a TA for the course of Signal Theory and had to help students in their coursework through Matlab/Octave.</p>\n<p>Things were different at the time because I had a syllabus to follow and most of my time was spent helping students if they were blocked coding-wise or had some questions regarding the theory.</p>\n<p>And of course - there was no AI. At least not in the sense that we speak about today - i.e. there were no LLMs.</p>\n<p>This time was different - I had the flexibility to choose what I was going to cover about Supervised Learning.</p>\n<p>I've never worked as a Data Scientist per se, but have been passionate about data for a while and spent a lot of time reading books and learning about the topic. In my previous company, I started playing with IMU data in my spare time which lead me to publish a paper at ICMLA where I used <a href=\"https://ieeexplore.ieee.org/document/9680024\" target=\"_blank\" rel=\"noopener noreferrer\">Support Vector Machine (SVM) for Step Detection using Nurvv trackers</a> and even open sourced the code <a href=\"https://github.com/DidierRLopes/step-detection-ML/tree/main\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2024-06-30-my-first-hand-experience-on-ai-impacting-education-through-perplexity-cursor-and-chatgpt_svm_paper.webp\"></p>\n<p>I've wrote about this and how I managed to write the entire code in my spare time in a single week, and missing the yearly team event in order to pull this off. You can read more about it <a href=\"https://didierlopes.com/blog/how-i-wrote-a-machine-learning-paper-in-1-week-that-got-accepted-to-icmla\">here</a>.</p>\n<p>But so the question is:</p>\n<p><em>\"Where do I start?\"</em></p>\n<p>My first intuition was to gather some of my favorite books and courses on the topic and understand how they presented the overall subject. I wouldn't have the same time, so I would need to touch on most topics briefly - enough for students to know about it and explore further if curious.</p>\n<p>However, given my time constraints with running OpenBB, I would have had a hard time since I would need to:</p>\n<ol>\n<li>Consume the content of these books and courses</li>\n<li>Mix and match them</li>\n<li>Cut to fit the time constraints</li>\n<li>Produce a final syllabus that I'm confident about</li>\n</ol>\n<br>\n<p>This was not a trivial task, and definitely not a weekend job.</p>\n<p>Except that <strong>IT WAS</strong>.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"perplexity-enters-the-chat\">Perplexity enters the chat<a href=\"https://didierlopes.com/blog/my-first-hand-experience-on-ai-impacting-education-through-perplexity-cursor-and-chatgpt#perplexity-enters-the-chat\" class=\"hash-link\" aria-label=\"Direct link to Perplexity enters the chat\" title=\"Direct link to Perplexity enters the chat\">​</a></h3>\n<p>Since Perplexity's main value proposition is being better at Google than Google - I popped the following prompt into it.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2024-06-30-my-first-hand-experience-on-ai-impacting-education-through-perplexity-cursor-and-chatgpt_perplexity.webp\"></p>\n<p>BAM.💥</p>\n<p>This was exactly what I was looking for.</p>\n<p>Did it give me the content end-to-end that I was expecting?</p>\n<p>No.</p>\n<p>Was it a perfect starting point?</p>\n<p>Yes.</p>\n<p>I didn't literally copy-paste it. I took the parts I liked, re-iterated on the ones I didn't until I eventually did. Plus, use my experience to prioritize parts that I felt should be more relevant vs others.</p>\n<p>Were there some hallucinations?</p>\n<p>Yes, it's not a silver bullet.</p>\n<p>But it saved me DAYS of work.</p>\n<p>I was dreading having to write the syllabus and like this, it was actually fun. It was fun because I felt like Perplexity was acting as my assistant and I was engaging in a conversation of what should be contained within the course and what shouldn't.</p>\n<p>After having all the content ready, I asked my wife to help me with some images to make it easier for students to understand concepts.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2024-06-30-my-first-hand-experience-on-ai-impacting-education-through-perplexity-cursor-and-chatgpt_assets.webp\"></p>\n<p>I was happy with the results - but wanted a second opinion. So I asked a friend of mine who's been a DS for over 6 years what his thoughts were on the materials I worked on - and he was impressed about the speed.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2024-06-30-my-first-hand-experience-on-ai-impacting-education-through-perplexity-cursor-and-chatgpt_ai_friend_message.webp\"></p>\n<p>Being a fan of open source, I have open sourced all the theory and practice of the course and you can access it here: <a href=\"https://github.com/DidierRLopes/supervised-learning\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/DidierRLopes/supervised-learning</a></p>\n<p>For the practice exercises I made it so that users can run it with colab directly on the browser to focus on the learning and not on the installation of libraries - highly recommend doing this.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2024-06-30-my-first-hand-experience-on-ai-impacting-education-through-perplexity-cursor-and-chatgpt_colab.webp\"></p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"assessing-students-grades\">Assessing students grades<a href=\"https://didierlopes.com/blog/my-first-hand-experience-on-ai-impacting-education-through-perplexity-cursor-and-chatgpt#assessing-students-grades\" class=\"hash-link\" aria-label=\"Direct link to Assessing students grades\" title=\"Direct link to Assessing students grades\">​</a></h2>\n<p>After presenting the classes to the students, they had to work on a final project that involved supervised learning - and I had to grade their work on it. The grade was from 0 to 5 and I was given freedom in terms of what criteria to use.</p>\n<p>So I did what someone else in my shoes would do.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"chatgpt-to-define-grading-criteria\">ChatGPT to define grading criteria<a href=\"https://didierlopes.com/blog/my-first-hand-experience-on-ai-impacting-education-through-perplexity-cursor-and-chatgpt#chatgpt-to-define-grading-criteria\" class=\"hash-link\" aria-label=\"Direct link to ChatGPT to define grading criteria\" title=\"Direct link to ChatGPT to define grading criteria\">​</a></h2>\n<p>I typed <a href=\"http://chat.openai.com/\" target=\"_blank\" rel=\"noopener noreferrer\">chat.openai.com</a> and had a conversation with ChatGPT about the best way to grade the coursework. I wanted it to be as fair as possible, but also evaluate students based on criteria outside of coding, such as problem formulation and documentation/clarity.</p>\n<p>Note: Story for another day but with the raise of LLMs, I have a very strong opinion that documentation and clarity will be as important as the code itself.</p>\n<p>This is the outcome of that conversation:</p>\n<blockquote>\n<p><strong>PART I - Problem Formulation</strong></p>\n<ul>\n<li>\n<p>1.a. <strong>Clarity and Definition:</strong> Is the problem clearly defined and well-formulated? Are the project's objectives explicitly mentioned?</p>\n</li>\n<li>\n<p>1.b. <strong>Relevance and Context:</strong> Is the relevance of the problem within the application domain explained? Does the problem justify the use of supervised learning?</p>\n</li>\n</ul>\n</blockquote>\n<br>\n<blockquote>\n<p><strong>PART II - Documentation and Quality</strong></p>\n<ul>\n<li>\n<p><strong>2.a. Code Quality and Readability:</strong> Clarity and Structure: Is the code well-organized with clear and consistent formatting? Are comments used effectively to explain complex logic? Best Practices: Does the code follow standard coding practices (e.g., naming conventions, modularization)? Are functions and classes used appropriately?</p>\n</li>\n<li>\n<p><strong>2.b. Documentation and Explanation in Comments or Notebook Markdown</strong>: Clarity: Are the results and methodology clearly documented? Is there a detailed explanation of the steps taken and the reasons behind them? Visualization: Are visual aids (e.g., graphs, plots) used to illustrate key points and results? Are these visualizations clear and informative?</p>\n</li>\n</ul>\n</blockquote>\n<br>\n<blockquote>\n<p><strong>PART III - Code</strong></p>\n<ul>\n<li>\n<p><strong>3.a. Data Preprocessing and Cleaning</strong>: Completeness: Are all necessary steps for data preprocessing included (e.g., handling missing values, encoding categorical variables, scaling features)? Justification: Are the preprocessing steps justified and explained? Is there a clear reason for the choices made?</p>\n</li>\n<li>\n<p><strong>3.b. Data Exploration</strong>: Initial Analysis: Is there an exploratory data analysis? Are descriptive statistics used to better understand the data? Visualization: Are visualizations (e.g., graphs, plots) used to illustrate data distribution, correlations, and important patterns? Are these visualizations clear and informative?</p>\n</li>\n<li>\n<p><strong>3.c. Model Implementation and Training</strong>: Correctness: Is the model implemented correctly according to the chosen algorithm? Are appropriate libraries and functions used? Parameter Tuning: Is there evidence of parameter tuning or optimization? Are the chosen parameters explained and justified?</p>\n</li>\n<li>\n<p><strong>3.d. Evaluation and Validation</strong>: Metrics: Are appropriate evaluation metrics chosen and calculated? Are these metrics relevant to the problem at hand? Validation Techniques: Are appropriate validation techniques used (e.g., cross-validation, train-test split)? Is there an analysis of the model's performance on both training and testing data?</p>\n</li>\n</ul>\n</blockquote>\n<br>\n<p>This was it.</p>\n<p>Exactly what I was looking for.</p>\n<p>Now I could grade a student on each of these criteria, then select a final grade weight for each criteria (e.g. 5-15%), create a spreadsheet with such a table and call it a day.</p>\n<p>However, the most time-consuming task was coming - the grading itself.</p>\n<p>There were 10 groups in total. So 10 notebooks that I had to look into, exploring completely different datasets with a different ML model being used, different ways to do exploratory data analysis, different ways to assess the model, different objectives, …</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"cursor-helping-with-grading\">Cursor helping with grading<a href=\"https://didierlopes.com/blog/my-first-hand-experience-on-ai-impacting-education-through-perplexity-cursor-and-chatgpt#cursor-helping-with-grading\" class=\"hash-link\" aria-label=\"Direct link to Cursor helping with grading\" title=\"Direct link to Cursor helping with grading\">​</a></h3>\n<p>I opened <a href=\"https://www.cursor.com/\" target=\"_blank\" rel=\"noopener noreferrer\">cursor</a> (which is basically VSCode + ChatGPT) and probably the software I've recommended the most to developers in 2024.</p>\n<p>And opened my first notebook.</p>\n<p>Then I thought, what if I had GPT-4o on my side - helping me to assess this coursework.</p>\n<p>It didn't need to be perfect because I was doing it myself, but it could help me understand if there was any critical thing that I missed OR if it completely had a different grade than the one I was going to provide - which would enable me to spend more time on that criteria and iterate.</p>\n<p>It gave me confidence that I was being fair to the students.</p>\n<p>And made me realize how hard it is for professors when they have 100s of students and have a subjective answer to grade. It's impossible to get it right. They try their best, but as soon as the answer is not binary (0 or 1), they are doomed to fail.</p>\n<p>So how did I do it?</p>\n<p>Given that I just wanted GPT-4o to quickly review each of the criterias based on the code, I created a prompt that I could use for all of notebooks that the students sent.</p>\n<p>This is what my setup looked like</p>\n<p align=\"center\"><img width=\"1000\" src=\"https://didierlopes.com/blog/2024-06-30-my-first-hand-experience-on-ai-impacting-education-through-perplexity-cursor-and-chatgpt_cursor.webp\"></p>\n<p>Having the code on the left side and the copilot on the right side that I could use to chat really enabled me to grade more confidently.</p>\n<p>Here's an example of a section of a response I got to one of the student's notebooks</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2024-06-30-my-first-hand-experience-on-ai-impacting-education-through-perplexity-cursor-and-chatgpt_cursor_output.webp\"></p>\n<p>One thing I did to have the copilot produce better outputs was to push it to do chain-of-thought (CoT). Meaning that I prompted the model to explain the reasoning behind a decision before providing a grade. This has been proved to yield to less hallucinations and more accurate responses - which is what I was looking for.</p>\n<p><strong>What if I wanted to do this at scale?</strong></p>\n<p>I would have put more effort into the prompt and focused on evaluating 1 criteria at a time. I would have done few-shot prompting where I put examples of what grades 1,2,3,4,5 look like for such criteria so the model has those references and can check for similarity of issues committed or successful tasks performed.</p>\n<p>Note: the model was able to interpret comments written in Portuguese which is another benefit.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"democratizing-access-to-tutors\">Democratizing access to tutors<a href=\"https://didierlopes.com/blog/my-first-hand-experience-on-ai-impacting-education-through-perplexity-cursor-and-chatgpt#democratizing-access-to-tutors\" class=\"hash-link\" aria-label=\"Direct link to Democratizing access to tutors\" title=\"Direct link to Democratizing access to tutors\">​</a></h2>\n<p>While I was working on my prompts to get some feedback from AI in terms of student's coursework I realized that I only need $20/mo to access them.</p>\n<p>But then I realized - so do the students.</p>\n<p>This means that the students have no reason to NOT run their entire coursework by a LLM that can act as a critic of their work.</p>\n<p>They can keep iterating until the model doesn't find anything - hence making students feel more confident about the work they are putting forward.</p>\n<p>My initial thought was: \"this feels like cheating\" (right after the - \"I wish I had this a few years ago\").</p>\n<p>But it actually isn't.</p>\n<p>Tutors have existed for a long time.</p>\n<p>Students pay tutors to spend time with them to learn outside of classes - whether it's explaining the theory or helping with coursework.</p>\n<p>However, tutors are a vitamin and not a painkiller (they are a nice-to-have and not a must-have). And because they aren't a requirement, it's not a typical choice among lower-income families.</p>\n<p>On the other hand, kids from wealthy families often have multiple tutors. Not for students who are almost failing their class, but who want to bump their grades from A- to an A+.</p>\n<p>But this is about to change.</p>\n<p>For the most part, GPT-3.5 is accessible for free.</p>\n<p>This means that everyone can have access to a tutor that they can work with to have better grades but also produce better coursework.</p>\n<p>This means that the concept of a tutor will be democratized and the playing field between students who come from different wealth backgrounds will be leveled and fair.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"a-final-thought-on-open-source\">A final thought on open source<a href=\"https://didierlopes.com/blog/my-first-hand-experience-on-ai-impacting-education-through-perplexity-cursor-and-chatgpt#a-final-thought-on-open-source\" class=\"hash-link\" aria-label=\"Direct link to A final thought on open source\" title=\"Direct link to A final thought on open source\">​</a></h2>\n<p>Another class that I had to give to students was \"Data Analytics in Financial Markets\".</p>\n<p>The goal here was to have a more real-life application of data analytics, particularly in financial markets - and even feature OpenBB which has partnered with this university.</p>\n<p>But when I started working on the content from scratch, I wondered.</p>\n<p>Can't I find a repository on GitHub that suits my needs?</p>\n<p>And I did.</p>\n<p>The GitHub repository I found was the GitHub repository that contains the code for the case studies in the O'Reilly book \"Machine Learning and Data Science Blueprints for Finance\" written by my friend <a href=\"https://www.linkedin.com/in/hariomtatsat/\" target=\"_blank\" rel=\"noopener noreferrer\">Hariom Tatsat</a>: <a href=\"https://github.com/tatsath/fin-ml\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/tatsath/fin-ml</a>.</p>\n<p>So why would I spend the time re-inventing the wheel when I could just walk students through a few of these case studies?</p>\n<p>This is what I did.</p>\n<p>Which then made me think that all of this data has been already fed into foundational models, and so even if I were to apply the same approach I did earlier with Perplexity or ChatGPT - it is likely that with a good prompt some of the main examples would have been derived from this repository.</p>\n<p>But in this case, this repository already had the perfect case-study format I was looking for, and so I can more easily credit the author.</p>\n<p>which made me wonder:</p>\n<p><em>How will open source authors be able to get credit for their work when all of it is being translated into weights in a big neural network architecture?</em></p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/my-first-hand-experience-on-ai-impacting-education-through-perplexity-cursor-and-chatgpt",
            "title": "My first-hand experience on AI impacting education through Perplexity, Cursor and ChatGPT",
            "summary": "AI will change education forever. Here's how I leveraged Perplexity, Cursor and ChatGPT to teach Supervised Learning and assess coursework.",
            "date_modified": "2024-06-30T00:00:00.000Z",
            "tags": [
                "ai",
                "education",
                "teaching",
                "llm",
                "chatgpt",
                "perplexity",
                "cursor",
                "supervised-learning",
                "edtech"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/why-chat-only-AI-Financial-Assistants-are-not-the-future",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2024-06-15-why-chat-only-AI-Financial-Assistants-are-not-the-future.webp\"></p>\n<p>Financial assistants structured like ChatGPT are great for quick searches but fall short for comprehensive investment research. They are limited by their one-dimensional approach, which hinders efficient data retrieval and long-term usability. Read on to discover how OpenBB Terminal Pro addresses these issues with a three-dimensional solution.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>This is a spicy take but bear with me.</p>\n<p>The more I think about \"ChatGPT for Finance\" products, the more I think this is not the answer.</p>\n<p>They are extremely good knowledge retrieval engines because you can ask what you want to know and get the answer immediately.</p>\n<p>My problem with their approach is what happens after.</p>\n<p>However, very little thought is given to the real-world investment workflow. That's why I strongly believe that a chat-only financial platform will never be successful on its own.</p>\n<p>Sure, they can win in the categories of \"search\" or \"screening\", but they won't be able to compete in the category of \"investment research platform\".</p>\n<p>To do that, they would need to evolve.</p>\n<p>Let me explain why and how OpenBB differs from them.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"1-dimensional-vs-n-dimensional\">1-Dimensional vs N-Dimensional<a href=\"https://didierlopes.com/blog/why-chat-only-AI-Financial-Assistants-are-not-the-future#1-dimensional-vs-n-dimensional\" class=\"hash-link\" aria-label=\"Direct link to 1-Dimensional vs N-Dimensional\" title=\"Direct link to 1-Dimensional vs N-Dimensional\">​</a></h2>\n<p>Financial assistants are, in general, 1-dimensional. By that, I mean that all you have on a screen is a \"dashboard\" with an unlimited y-axis (1 single dimension).</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2024-06-15-why-chat-only-AI-Financial-Assistants-are-not-the-future_1.webp\"></p>\n<p>This means that whatever information they output will always be in the same position, which is great for the short term.</p>\n<p>But for the long term? Not so much. If the user wants to find specific information, they will need to keep scrolling up the text to find it.</p>\n<p>When financial assistants allow multiple conversations, then we start having 2 dimensions, where each conversation introduces a new axis.</p>\n<p>The problem with this approach is that you can't easily find data within one of those past conversations since the assistant focuses on answering your question and not on data retrieval from the previous outputs.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"our-3-dimensional-solution-on-terminal-pro\">Our 3-dimensional solution on Terminal Pro<a href=\"https://didierlopes.com/blog/why-chat-only-AI-Financial-Assistants-are-not-the-future#our-3-dimensional-solution-on-terminal-pro\" class=\"hash-link\" aria-label=\"Direct link to Our 3-dimensional solution on Terminal Pro\" title=\"Direct link to Our 3-dimensional solution on Terminal Pro\">​</a></h2>\n<p>How do we handle those issues? We have 3 dimensions.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2024-06-15-why-chat-only-AI-Financial-Assistants-are-not-the-future_2.webp\"></p>\n<p>Our Terminal Pro has a Copilot on the side, similar to other financial assistants.</p>\n<p>However, its big advantage is that when you want to save Copilot's output for later, you can convert it into a text widget. And when you do so, you can place it wherever you want in this space — with the axis being infinite vertical scroll, tabs, dashboards, and folders.</p>\n<video controls=\"\"><source src=\"https://openbb-cms.directus.app/assets/ebdda68a-95f7-425b-aebe-5c98936c9189\"></video>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"storage-based-solutions-are-not-optimized-for-investment-research\">Storage-based solutions are not optimized for investment research<a href=\"https://didierlopes.com/blog/why-chat-only-AI-Financial-Assistants-are-not-the-future#storage-based-solutions-are-not-optimized-for-investment-research\" class=\"hash-link\" aria-label=\"Direct link to Storage-based solutions are not optimized for investment research\" title=\"Direct link to Storage-based solutions are not optimized for investment research\">​</a></h2>\n<p>Again, financial assistants are optimized for search rather than information storage.</p>\n<p>This means that, by nature, chat-only financial assistants assume that their output will not matter in the future, so they answer your queries similarly to how a text conversation works. It's literally called ChatGPT for that reason.</p>\n<p>However, that's not ideal for investment research.</p>\n<p>If analysts and researchers need to access these financial assistants' output at some point in the future, they won't be able to do it quickly. Instead, they'll have to go through a long chat history.</p>\n<p>This is why, in our Terminal Pro, we allow users to create a markdown-based text widget from the Copilot's output, as shown above, so that you can have that information quickly accessible, but also editable.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"theres-no-simple-way-to-know-where-the-data-comes-from\">There's no simple way to know where the data comes from<a href=\"https://didierlopes.com/blog/why-chat-only-AI-Financial-Assistants-are-not-the-future#theres-no-simple-way-to-know-where-the-data-comes-from\" class=\"hash-link\" aria-label=\"Direct link to There's no simple way to know where the data comes from\" title=\"Direct link to There's no simple way to know where the data comes from\">​</a></h2>\n<p>Financial assistants are great, and they are improving every day. But if there's something I've learned from talking with financial firms for over three years, it's that this is a very slow-moving industry, and adopting new technologies takes time.</p>\n<p>But with AI, it seems different. It's so revolutionary that people are willing to incorporate it into their workflow faster because they immediately understand the benefits it can bring to their business.</p>\n<p>However, hallucinations are still a big problem — so it's essential for these firms to be able to verify the raw data and sources.</p>\n<p>The current level of AI is equivalent to having a smart intern that you would need to double-check their work or trust but verify.</p>\n<p>This is why our Copilot always answers based on data that is readily available on the dashboard — and (due to our \"Bring Your Own Data\" technology) that data can be brought by your firm rather than being limited to what we offer out of the box.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2024-06-15-why-chat-only-AI-Financial-Assistants-are-not-the-future_3.webp\"></p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"financial-chats-are-not-collaborative\">Financial chats are not collaborative<a href=\"https://didierlopes.com/blog/why-chat-only-AI-Financial-Assistants-are-not-the-future#financial-chats-are-not-collaborative\" class=\"hash-link\" aria-label=\"Direct link to Financial chats are not collaborative\" title=\"Direct link to Financial chats are not collaborative\">​</a></h2>\n<p>Financial assistants are not collaborative by default.</p>\n<p>When someone opens a tool like ChatGPT, they are interested in getting an answer to their question. Can you imagine what would happen if more people had access to that conversation and asked ChatGPT a different question? That would translate into a horrible user experience.</p>\n<p>The interesting thing is that investment research starts as an individual process but ends up being a collaborative effort where the findings are shared and discussed within a team.</p>\n<p>So, financial assistants have a challenging task: multiple people on a team should be able to access all the conversations without being able to interact with these chats.</p>\n<p>But what if you go through a colleague's chat where they were asking questions about a company's earnings, and you want to do a follow-up question?</p>\n<p>That's a complex problem.</p>\n<p>At OpenBB, we are in a very good position to solve this for our users.</p>\n<p>Since we allow them to create a widget from their conversation with the Copilot, users can effectively create the ideal dashboard to share with their team. On their turn, other team members will then be able to use the Copilot on that same dashboard to make their questions.</p>\n<p>And guess what?</p>\n<p>This can be considered yet another dimension that we allow users to explore.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2024-06-15-why-chat-only-AI-Financial-Assistants-are-not-the-future_4.webp\"></p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"wrap-up\">Wrap up<a href=\"https://didierlopes.com/blog/why-chat-only-AI-Financial-Assistants-are-not-the-future#wrap-up\" class=\"hash-link\" aria-label=\"Direct link to Wrap up\" title=\"Direct link to Wrap up\">​</a></h2>\n<p>In a nutshell,</p>\n<ul>\n<li>\n<p>Most AI financial assistant products are 1-dimensional. Great at retrieving an answer quickly but poor at the overall task of doing investment research.</p>\n</li>\n<li>\n<p>OpenBB Terminal Pro is positioning itself as a flexible and customizable investment research platform with N-dimensions that an AI copilot can control to produce a full investment dashboard as if it were an analyst.</p>\n</li>\n</ul>\n<p>I'm biased, but once we provide the OpenBB Copilot with the capability to interact with the interface (create widgets, dashboards and folders) we might be the company that gets closest to replace an analyst's job.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/why-chat-only-AI-Financial-Assistants-are-not-the-future",
            "title": "Why chat-only AI financial assistants are not the future",
            "summary": "Financial assistants structured like ChatGPT are great for quick searches but fall short for comprehensive investment research.",
            "date_modified": "2024-06-15T00:00:00.000Z",
            "tags": [
                "openbb",
                "ai",
                "fintech",
                "workspaces",
                "investment-research",
                "chatbots",
                "ui",
                "ux",
                "collaboration"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/29-years-old-and-sitting-on-the-top-of-giants",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2024-06-05-29-years-old-and-sitting-on-the-top-of-giants.webp\"></p>\n<p>Yesterday was my 29th birthday, and I was reflecting on my life and on how sitting on the top of giants isn’t given enough credit. My giants are my parents.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>Yesterday I turned 29 years old.</p>\n<p>The night before, I was speaking with my dad about how grateful I am for everything he’s done for my brother and I.  I always had everything - food at the table, a roof and education.</p>\n<p>I’m the person I am today because of my parents.</p>\n<p>But my dad didn’t have it easy.</p>\n<p>And so instead of writing about how grateful I am for the life I have today, I want to share some parts of my dad’s life.</p>\n<p>I don’t like to share personal information about my family, but I feel like from all the posts I read on success - sitting on the top of giants isn’t given enough credit.</p>\n<p>My giants are my parents.</p>\n<p>Here’s his story.</p>\n<p>My dad grew up with very little in a town in the middle of nowhere in Portugal with 6 siblings.</p>\n<p>He did a few years in school and after classes he would come home and watch his parents sheep until it was dark. He did his homework during that time since there was no electricity back then.</p>\n<p>If a sheep ran away while he was doing his homework, his dad would punish him with whatever was at hand, a stick or a belt.</p>\n<p>Times were different back then.</p>\n<p>In school, if he got questions like 7x8 wrong, teachers wouldn’t just say the correct answer. They had a special ruler that was used to hit a student’s hand.</p>\n<p>Again, times were different.</p>\n<p>After a couple of years in school - he didn’t like it (I wonder why eh) and they didn’t have a lot of money. So he started working at the age of 11 in construction.</p>\n<p>An 11 year old kid, taking 2 buckets of cement up and down the stairs to build houses.</p>\n<p>At the age of 17 he moved to Geneva (Switzerland) for a better paid job, as a bricklayer but also did painting jobs and similar.</p>\n<p>At 18, his mum died.  She was run over by a car near our hometown.</p>\n<p>At 20, he had to come to Portugal because of his passport and he met my mum.</p>\n<p>1 year later, my mum moved to Geneva to be with him. She worked in a factory making boxes for Rolex watches.</p>\n<p>At 22, his dad died from a disease.</p>\n<p>He kept working his ass off. 6 days a week, starting at 6 am whether it was snowing, raining or extremely hot.</p>\n<p>No travelling or unnecessary expenses, except tobacco, it was his only addiction as everyone around him smoked - it was a social thing.</p>\n<p>At 24 he got married with my mum. My mum’s family didn’t like his, so they didn’t attend the wedding and they had to cover it with all of their savings.</p>\n<p>At 31, he had me.</p>\n<p>The week before I was born would be the last he would ever smoke, since my mum said that she didn’t want smoke near us because of our health. At some point he was smoking 2 packs a day, and he stopped from one day to the other which is wild.</p>\n<p>At 32 his painting shift had just finished and his boss asked him to give one more painting layer to the outside of an apartment. And he went up the ladder, and it broke. He fell from a 2-story apartment on his foot, and his foot bone got smashed into pieces. (He had actually mentioned to his boss that the ladder didn’t feel very stable earlier that day).\n The doctor told him that he would never be able to do any physical work ever again. 24 years later, and he still struggles to walk for long periods of time.</p>\n<p>At 33, he had my brother.</p>\n<p>Because of the accident, he stayed at home to raise my brother and I.</p>\n<p>A bit after, Portugal joined the Euro. So my dad thought that the living conditions in Portugal would improve overall like other European countries (spoiler alert: it didn’t).</p>\n<p>So, he decided to start building a house on the same land where his hometown house was, in Portugal.</p>\n<p>They couldn’t afford to buy a house in Geneva, but had enough savings that they could build one in his hometown.</p>\n<p>They went back when he was 39 (I was 8), and that’s where I grew up.</p>\n<p>My mum struggled to find a job for many years - she only got a job as a secretary at a furniture store - until they went bankrupt.</p>\n<p>My dad had depression since he was stuck at home with nothing to do.</p>\n<p>Growing up, I wanted to work as a bricklayer in summers to make some cash and my dad forbid me doing so.</p>\n<p>He said that it was dangerous and he didn’t want me to have that life. He has seen a lot of young people dropping out of school because they start receiving salaries early and prioritise short-term outcomes over long-term ones.</p>\n<p>He didn’t want me to follow that path.</p>\n<p>He wanted to give me the opportunities that he didn’t have growing up. And he did.</p>\n<p>One day I got home from high school, and commented that someone I knew always had expensive clothes and watches. He happened to know their family and got upset. He was upset because he knew that they owed a lot of money to a lot of people - and kept living a luxury lifestyle.\n So he told me “You may not wear all of that, but you will never hear in your life that we owe anything to anyone. Everything you have has been bought with a lot of hard work from your mother and I, and not by stealing or owing anything to anyone”.</p>\n<p>I still think about this often, and how appearances are often just that.</p>\n<p>A few years later after I got into university, my parents decided to move back to Switzerland.</p>\n<p>My mum still didn’t have a job and we weren’t going home as much (we both studied relatively far from our hometown). It was hard on her to move away from us, but it was the right thing to do.</p>\n<p>She found a job as a cleaner, which she has been doing for almost 10 years now.</p>\n<p>In the meantime my dad wondered if he could leverage all the skills he had learned growing up to manage a housing project. So he bought land in Portugal, and was heavily involved in the management of the project. Meaning he worked across everything, except the physical aspects of the job.</p>\n<p>It was an investment, but after having so many years in real estate - it was hard for someone to have as much knowledge breadth as he did in terms of costs of materials and staff since he had been on the other side of the coin for a long time.</p>\n<p>Now he does that every now and then, which keeps him busy. But since it involves being far from my mum, this time he’s hiring an agency to be more involved at the expense of less headaches and a lower margin.</p>\n<p>He has a good life now. But he came from nothing, literally.</p>\n<p>Most people on his shoes, don’t make it.</p>\n<p>Damn.</p>\n<p>Most people with more opportunities than him don’t make it.</p>\n<p>I often feel guilty because I get to live life in a way that my parents could never.</p>\n<p>The best way I can think to repay them is to work hard and show them that their hard life will be the last that the future Lopes generation will have to endure.</p>\n<p>That and hopefully buying them a nice car one day.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/29-years-old-and-sitting-on-the-top-of-giants",
            "title": "29 years old and sitting on the top of giants",
            "summary": "Yesterday was my 29th birthday, and I was reflecting on my life and on how sitting on the top of giants isn’t given enough credit. My giants are my parents.",
            "date_modified": "2024-06-05T00:00:00.000Z",
            "tags": [
                "birthday",
                "dad",
                "family"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/rabbit-r1-there-is-hope",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2024-04-28-rabbit-r1-there-is-hope.webp\"></p>\n<p>I can see a future where people use rabbit r1 for very particular use cases where phone is suboptimal. For instance, when multiple people want to interact with said phone (e.g. selecting music at a party without having to give phone away) and that is not ideal due to personal information on phone, or when the phone isn't ideal because it has too many distractions and user wants to focus on doing something (e.g. practicing a presentation using recording session and then asking for feedback).</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"what-is-the-rabbit-r1\">What is the rabbit r1<a href=\"https://didierlopes.com/blog/rabbit-r1-there-is-hope#what-is-the-rabbit-r1\" class=\"hash-link\" aria-label=\"Direct link to What is the rabbit r1\" title=\"Direct link to What is the rabbit r1\">​</a></h2>\n<p>Rabbit r1 was first introduced at CES 2024 as a pocket AI companion (watch the keynote <a href=\"https://www.rabbit.tech/rabbit-r1\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>).</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2024-04-28-rabbit-r1-there-is-hope_1.webp\"></p>\n<p>The main distinction over being just a \"ChatGPT on-the-go\" is the fact that they introduced what they call a Large Action Model (LAM), which is an agent capable of taking requests and making different function calls (e.g., translation, weather, finance, vision, taking notes, and more).</p>\n<p>There are now quite a few consumer products that are trying to win this category. Here are a few:</p>\n<ul>\n<li>\n<p><a href=\"https://humane.com/\" target=\"_blank\" rel=\"noopener noreferrer\">AI pin</a> from Humane. MKBHD did a good <a href=\"https://www.youtube.com/watch?v=TitZV6k8zfA\" target=\"_blank\" rel=\"noopener noreferrer\">review</a> on this product (or should I say 'bad review'?).</p>\n</li>\n<li>\n<p><a href=\"https://www.limitless.ai/\" target=\"_blank\" rel=\"noopener noreferrer\">pendant</a> from Limitless (previously Rewind AI).</p>\n</li>\n<li>\n<p><a href=\"https://www.openinterpreter.com/\" target=\"_blank\" rel=\"noopener noreferrer\">01</a> from Open Interpreter. I ordered this one because it's <a href=\"https://github.com/OpenInterpreter/open-interpreter\" target=\"_blank\" rel=\"noopener noreferrer\">open source</a> and I can build on top.</p>\n</li>\n</ul>\n<p>While at the surface these devices are somewhat similar, they approach the problem from a different angle. AI pin relies on users to clip their device to their clothes, the pendant is put on the collar of your top and 01 is held handheld. Rabbit r1 is also handheld, but unlike the others contains a screen to interact with - so it's closer to a phone than the others.</p>\n<p>Nonetheless, according to Jesse (rabbit's CEO) they are currently the most successful AI device in terms of sales (sold over 100,000 rabbit r1 in a few weeks).</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"how-i-got-my-r1\">How I got my r1<a href=\"https://didierlopes.com/blog/rabbit-r1-there-is-hope#how-i-got-my-r1\" class=\"hash-link\" aria-label=\"Direct link to How I got my r1\" title=\"Direct link to How I got my r1\">​</a></h2>\n<p>My wife saw me watching a few videos of rabbit r1 and decided to surprise me with one, a one-time $199 purchase without any subscription fee. I wonder why she didn’t do it when I was watching Apple Vision Pro 😄.</p>\n<p>But they didn’t ship immediately. My batch was only meant to be shipped sometime in June. However, rabbit tweeted that there would be a Pickup Party in NYC. I added notifications on their X account and once they announced that registrations were open I was ready. I RSVPd and this week I attended the event to grab mine.</p>\n<p>The event was well organized. One thing is for sure, rabbit knows how to build a community and hype with their users.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2024-04-28-rabbit-r1-there-is-hope_2.webp\"></p>\n<p>The keynote presented at the event can be found <a href=\"https://www.rabbit.tech/live-unboxing\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>. In it, rabbit's CEO unboxes a rabbit r1 and shows everything it can do on stage.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"my-experience\">My experience<a href=\"https://didierlopes.com/blog/rabbit-r1-there-is-hope#my-experience\" class=\"hash-link\" aria-label=\"Direct link to My experience\" title=\"Direct link to My experience\">​</a></h2>\n<p>I have been playing with rabbit r1 for a couple of days now. A few funny things I've done since:</p>\n<ul>\n<li>\n<p>Jailbreak rabbit r1 to say <a href=\"https://x.com/didier_lopes/status/1783335809459859708\" target=\"_blank\" rel=\"noopener noreferrer\">f*ck which falls outside the guidelines</a></p>\n</li>\n<li>\n<p>Ask it what LLM it was using under the hood, to which it said <a href=\"https://x.com/didier_lopes/status/1783346493832753477\" target=\"_blank\" rel=\"noopener noreferrer\">it was using a fine-tuned version of OpenAI's GPT-3</a></p>\n</li>\n<li>\n<p>Have rabbit r1 make a <a href=\"https://x.com/didier_lopes/status/1784228313717776505\" target=\"_blank\" rel=\"noopener noreferrer\">Deez Nuts joke</a></p>\n</li>\n<li>\n<p>Use rabbit r1 as a <a href=\"https://x.com/didier_lopes/status/1784357946920505387\" target=\"_blank\" rel=\"noopener noreferrer\">Not Hotdog app</a> (<a href=\"https://www.imdb.com/title/tt2575988/\" target=\"_blank\" rel=\"noopener noreferrer\">Silicon Valley reference</a>)</p>\n</li>\n</ul>\n<p>But now onto the serious stuff. Since I was at the Pickup Party where Jesse split the presentation based on the major features of the products, I want to address each of these individually after having time to play with them.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"search\">Search<a href=\"https://didierlopes.com/blog/rabbit-r1-there-is-hope#search\" class=\"hash-link\" aria-label=\"Direct link to Search\" title=\"Direct link to Search\">​</a></h3>\n<p>For search, rabbit r1 relies on <a href=\"https://www.perplexity.ai/\" target=\"_blank\" rel=\"noopener noreferrer\">Perplexity</a>. I'm a Perplexity fan myself and at some point I even replaced my default <a href=\"https://arc.net/\" target=\"_blank\" rel=\"noopener noreferrer\">Arc browser</a> search engine with Perplexity. This only lasted one day because then I realized how many times I just wanted to end up on a landing page or on someone's LinkedIn/X. It made me realize why Google is, well, Google. Regardless, this is something that I do with my phone, and so I don't think it's a strong use case.</p>\n<p>However, if you have a kid that is curious to understand the world. I think a rabbit r1 is well worth it to use it to ask questions that they are curious about, without having the distractions that a phone provides.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"vision\">Vision<a href=\"https://didierlopes.com/blog/rabbit-r1-there-is-hope#vision\" class=\"hash-link\" aria-label=\"Direct link to Vision\" title=\"Direct link to Vision\">​</a></h3>\n<p><strong>What is this</strong> - I just don't think this is a strong use case overall. This is not something that you do daily, weekly, or even monthly. Maybe once a year or so. The last time I did it was last year in Mexico to know the name of an animal that was nearby. I went to Google and looked for \"Mexico animal that looks like a racoon\" and the first answer was Coati which was what I was looking for. If that query didn't work, I would have taken a picture of the animal and then Google search - but that's my second choice because of the effort of doing so. This to say that it's not really a pain point that users will have.</p>\n<p><strong>Edit spreadsheet</strong> - This is a somewhat interesting use case choice, I wonder if they picked it up because no other device showed being capable of doing this (taking a picture to a handwritten table, asking for a change and emailing the image to your email). Personally, I don't write tables that much anymore on paper, and the ones I do are small enough that if I want to transcribe it takes me seconds to do. It may be a strong use case for certain jobs, but I’m not sure about it, nor the performance it would have on large tables. The example Jesse shared at the event was a 5x3 tabl.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"terminal-mode\">Terminal mode<a href=\"https://didierlopes.com/blog/rabbit-r1-there-is-hope#terminal-mode\" class=\"hash-link\" aria-label=\"Direct link to Terminal mode\" title=\"Direct link to Terminal mode\">​</a></h3>\n<p>It’s like using ChatGPT but with a worse interface. The keyboard reminds me of BlackBerry but it’s gimmicky to use - personally, I didn’t like the experience. I would always pick up my phone to use ChatGPT over using the Terminal mode for instance.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2024-04-28-rabbit-r1-there-is-hope_3.webp\"></p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"translation\">Translation<a href=\"https://didierlopes.com/blog/rabbit-r1-there-is-hope#translation\" class=\"hash-link\" aria-label=\"Direct link to Translation\" title=\"Direct link to Translation\">​</a></h3>\n<p>YES. Having Portuguese parents that don’t speak english, whenever they are with my wife, I need to be the translator. So having a device that allows them to translate in “real-time” both ways is a huge value add.</p>\n<p>Yes, I know that Google already has this feature - but it's shit and if you disagree, you never actually used it. LLMs can understand expression and meaning, in a way that a model like BERT cannot. I actually did this post where I prompted ChatGPT to do exactly this - act as a device that stays in the middle of a conversation translating from one language to another based on who the speaker was (tweet <a href=\"https://x.com/didier_lopes/status/1740049615804846461\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>, it went kind of viral).</p>\n<p>Sure, this could be an app, but I quite like the idea of having a device that just does this. I think that’s because the translation works both ways, so I imagine you passing the device to the other person to press the button when they want to speak. So that way, it feels more like a “common” object whereas your phone is more personal.</p>\n<p>Although I was excited about this, and it was the first thing I tried it failed badly. The CTO of the company <a href=\"https://x.com/LiaoPeiyuan/status/1783001793573843078\" target=\"_blank\" rel=\"noopener noreferrer\">replied</a> to <a href=\"https://x.com/didier_lopes/status/1783000272278569412\" target=\"_blank\" rel=\"noopener noreferrer\">my tweet</a> saying that they are working on fixing it.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2024-04-28-rabbit-r1-there-is-hope_4.webp\"></p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"notes\">Notes<a href=\"https://didierlopes.com/blog/rabbit-r1-there-is-hope#notes\" class=\"hash-link\" aria-label=\"Direct link to Notes\" title=\"Direct link to Notes\">​</a></h3>\n<p>Yay, another note-taking app. NOT. I’d prefer an integration with the Apple Notes app or Notion, so I don’t need to then go into yet another website and copy-paste those notes to some other place.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2024-04-28-rabbit-r1-there-is-hope_5.webp\"></p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"voice-recording\">Voice Recording<a href=\"https://didierlopes.com/blog/rabbit-r1-there-is-hope#voice-recording\" class=\"hash-link\" aria-label=\"Direct link to Voice Recording\" title=\"Direct link to Voice Recording\">​</a></h3>\n<p>The voice recording feature is pretty good. If you are a content creator (e.g., writer, youtuber), I think this is very powerful. The way I see it is that rabbit offers way less distractions than your phone, so you could go on a walk and take r1 and just speak with it to brainstorm ideas. Then go to the website and analyze your ideas to transform it into content.</p>\n<p>Personally, when I have ideas like this I just drop a voice note to my wife’s WhatsApp and then mark the message as unread. It’s hacky but it works and I've been doing it for a long time now. We have an inside joke where I start these audios with “Note to self” and she always makes fun of it.</p>\n<div class=\"flex justify-center gap-2\"><img src=\"https://didierlopes.com/blog/2024-04-28-rabbit-r1-there-is-hope_6.webp\" width=\"50%\"><img src=\"https://didierlopes.com/blog/2024-04-28-rabbit-r1-there-is-hope_7.webp\" width=\"50%\"></div>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"music\">Music<a href=\"https://didierlopes.com/blog/rabbit-r1-there-is-hope#music\" class=\"hash-link\" aria-label=\"Direct link to Music\" title=\"Direct link to Music\">​</a></h3>\n<p>Last year for my birthday my wife gave me a <a href=\"https://divoom.com/products/divoom-pro\" target=\"_blank\" rel=\"noopener noreferrer\">Divoom Ditoo-Pro Retro</a> - it does a lot of things (e.g. music, radio, alarm, voice memo, games, music, planner, pixel art). Honestly, I just use it for music. It lived in my car during the entire year as a speaker since I didn't have bluetooth audio in the car. I think the advantage of rabbit r1 over it is that I can use my voice to change the music, which is handy if you are driving. On the other hand, my Divoom allows me to listen to my audibles since it acts as a bluetooth speaker whereas rabbit r1 would need an audible integration.</p>\n<p>I think this can be a compelling use case as sitting in the middle of the table at a dinner or party with friends, where if someone wants to change the music they can just use the rabbit r1 to ask for something - and this way you can keep your phone/laptop on you instead of using it for everybody else to touch.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"apps\">Apps<a href=\"https://didierlopes.com/blog/rabbit-r1-there-is-hope#apps\" class=\"hash-link\" aria-label=\"Direct link to Apps\" title=\"Direct link to Apps\">​</a></h3>\n<p><strong>Doordash/Uber</strong> - I haven’t tried it yet, but I feel like the phone is so good at it already and with a rich UI/UX, that I don’t see the point in using rabbit r1.</p>\n<p><strong>Generative AI</strong> - This is an interesting use case. Personally I don’t use Midjourney so I'm not the target audience. I do find it interesting that you can generate these images on the go on r1 directly without having to go through Discord (suboptimal) experience. I'm excited about the opportunities that this presents - for instance, integrating with <a href=\"https://openbb.co/products/bot\" target=\"_blank\" rel=\"noopener noreferrer\">OpenBB Bot</a> to display financial data on rabbit r1 directly.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"teach-mode\">Teach mode<a href=\"https://didierlopes.com/blog/rabbit-r1-there-is-hope#teach-mode\" class=\"hash-link\" aria-label=\"Direct link to Teach mode\" title=\"Direct link to Teach mode\">​</a></h3>\n<p>Jesse showed a brief preview of how teach mode works but mentioned that this feature is not yet available and they want to nail the user experience and add guardrails so users cannot use it for something malicious. I'm very excited about the teach mode prospect, since I think this falls in the category of \"app creation\" and allows users to use the device for very specific needs, hence opening the total addressable market.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"conclusion\">Conclusion<a href=\"https://didierlopes.com/blog/rabbit-r1-there-is-hope#conclusion\" class=\"hash-link\" aria-label=\"Direct link to Conclusion\" title=\"Direct link to Conclusion\">​</a></h2>\n<p>First of all, the rabbit r1 is beautiful. It's light, well made and has this bright appealing color. This isn't surprising since it was done in collaboration with <a href=\"https://teenage.engineering/\" target=\"_blank\" rel=\"noopener noreferrer\">Teenage Engineering</a> (a company known for making products that I want without knowing what they do).</p>\n<p>This may be controversial, but the thing I like the least about the hardware is the button being located on the right side. The reason why I hate that decision is that I cannot easily use the device with one hand only. If I try, it becomes very gimmicky where I do gymnastics just to press the button. I don't get why they didn't make it right under the scrolling wheel, it would resemble more a controller/phone which is something that our hands have long been accustomed to. Even if the button was located on the upper side of the device, the UX would be MUCH better.</p>\n<p>That's one of my biggest complaints against the hardware itself, see image below to see what I mean. I almost need to bend my right thumb in order to reach the button which is used very often. One can argue that I can wrap my hands more around the device to give a better experiencing in clicking the button which is 100% true, HOWEVER, if I do that then I can't reach the wheel to scroll.</p>\n<div class=\"flex justify-center gap-2\"><img src=\"https://didierlopes.com/blog/2024-04-28-rabbit-r1-there-is-hope_8.webp\" width=\"50%\"><img src=\"https://didierlopes.com/blog/2024-04-28-rabbit-r1-there-is-hope_9.webp\" width=\"50%\"></div>\n<br>\n<p>Also, related with the picture from the above. The battery is pretty weak, it needs to be charged often.</p>\n<p>The rabbit r1 OS has a lot of room for improvement, a few things I've experienced:</p>\n<ul>\n<li>Having a black screen that doesn't recover until I manually power off device;</li>\n<li>Not triggering the function I want - sometimes it looks for a specific wording, e.g. \"start a recording session\" works but \"do a voice recording\" does not. I would have expected for it to be able to understand intent;</li>\n<li>Sometimes I get a \"The app is under maintenance. Please try again later\" for functions that I know it is capable of doing;</li>\n<li>Every few minutes getting \"unable to connect to Rabbit OS\";</li>\n<li>Randomly losing the previous context - I assume this is because of the number of tokens that can fit in the context?;</li>\n<li>Spotify integration broken;</li>\n<li>Even though it knows my location (due to getting weather app location correct), the time is not correct and I can't update it through the settings.</li>\n</ul>\n<p>But this is also the first product version and LLMs are by nature non-deterministic so these type of bugs are kind of expected.</p>\n<p>It's a one-time $199 price tag. There's no recurring subscription. As a consumer, I like this a lot. A one-time purchase allows users to buy the product to experiment without any strong commitment (apart from that one-time fee of course). In terms of economics, I'm not sure how Rabbit will handle a growing user base and better LLMs. During the event, they mentioned a partnership with both OpenAI and Anthropic. If they are using one of these models, someone needs to be paying for these tokens. For instance, for <a href=\"https://openbb.co/products/pro\" target=\"_blank\" rel=\"noopener noreferrer\">OpenBB Terminal Pro</a> we decided to allow usage similarly to how the ChatGPT free tier works, which basically rate limits based on usage and allows us to keep our costs controlled.</p>\n<p>Meta is attempting to commoditize LLMs, so if I were in rabbit's shoes I would consider hosting <a href=\"https://llama.meta.com/llama3/\" target=\"_blank\" rel=\"noopener noreferrer\">Llama 3</a> locally and providing inference from this directly. Maybe even do a partnership with <a href=\"https://groq.com/\" target=\"_blank\" rel=\"noopener noreferrer\">Groq</a> for users paying a small subscription - not so much because of the impressive 800 tokens/s inference (using Llama 3) since rabbit r1 uses voice and inference speed is less relevant, but for the cold start (i.e. the lag between user question and output). Meta's commercial license only applies to companies with over 700 Million active users, so I think Rabbit would be good for some time.</p>\n<p>Personally, I wouldn’t recommend rabbit r1 as a phone alternative. Not even close. If someone says that they stopped using their phone after having their rabbit r1, I can guarantee you that they weren’t using their phone a lot anyway. I agree a lot with MKBHD in saying <a href=\"https://www.youtube.com/watch?v=TitZV6k8zfA\" target=\"_blank\" rel=\"noopener noreferrer\">Phones are OP</a>.</p>\n<p>But if you are reading this, you are probably wondering what are the use cases where I would recommend Rabbit r1. So let's do that.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"this-is-a-buy-if\">This is a buy if<a href=\"https://didierlopes.com/blog/rabbit-r1-there-is-hope#this-is-a-buy-if\" class=\"hash-link\" aria-label=\"Direct link to This is a buy if\" title=\"Direct link to This is a buy if\">​</a></h3>\n<ul>\n<li>\n<p>For kids that are curious and want to learn more about the world. Being able to have it before a phone, is very compelling. Imagine your kid being able to ask r1 what a word means and how to use it in a sentence, who person X is, how something works, to practice learning another language, as a complement when reading a book/studying. The advantage over the phone is that it doesn't have any other distractions. It would basically be Perplexity on the go, and thus the Perplexity tagline \"Where knowledge begins\" makes total sense.</p>\n</li>\n<li>\n<p>As a device for two-way translation. The two-way is important, because if it’s just one-way then using the phone is preferred. But being two-way allows for both people to interact with the device, which in my opinion is less personal than a phone and more like a gadget. We aren't there yet, but I'm sure the model will keep improving and becoming better at this.</p>\n</li>\n<li>\n<p>For content creators who want to “zone out” and leave their phone at home and just use the record feature to record content, whether that is a blog post, a new lyrics or a podcast idea.</p>\n</li>\n<li>\n<p>As a music device to be at the center of a table at a dinner, in the corner at a party selecting the tunes or on a roadtrip. People will enjoy interacting with it due to its unique nature, and that way you don't need to be blocked from using your phone.</p>\n</li>\n<li>\n<p>As a virtual assistant. If the alarm feature was already implemented, I would've likely already replace my Alexa, since rabbit r1 looks much nicer. Even more with the cool standing case.</p>\n</li>\n</ul>\n<p>... and of course, the use case is worth $200 for you. There are likely devices that can achieve the same for a cheaper cost. I like the fact that is state-of-the-art and they are trying to innovate.</p>\n<p>Also, the rabbit effect going up and down waiting to be prompted and the hears going up when listening is pretty sweet - see it <a href=\"https://didierlopes.com/assets/files/2024-04-28-rabbit-r1-there-is-hope_10-91728068728241d692bfecaa17d39db2.webp\" target=\"_blank\">here</a>.</p>\n<p>In any case, there are two recurring topics in these use cases, so let's talk about each individually.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"main-use-cases\">Main use cases<a href=\"https://didierlopes.com/blog/rabbit-r1-there-is-hope#main-use-cases\" class=\"hash-link\" aria-label=\"Direct link to Main use cases\" title=\"Direct link to Main use cases\">​</a></h3>\n<ol>\n<li>\n<p><strong>A very targeted use case</strong> - The phone can be a double-edged sword. On the one hand, it's your door to the world and what's happening. On the other hand, it's your door to the world and what's happening. I say it this way because this can be extremely good or bad depending on the use case. Phones are optimized for users to spend time on them, apps are optimized to provide dopamine hits so users use them for longer. Notifications will interrupt you throughout the day so you remember to go back to the app, etc.. But sometimes you only want to do 1 thing, and don't want to be distracted from it. The best example are E-Books. You can read on your phone, iPad or laptop - yet people decide to buy a kindle so they can just do that. Read with no distractions. You are paying a premium for a product to remove the distractions. I believe that rabbit r1 can achieve this, particularly if they allow developers to build specific apps for specific use cases.</p>\n</li>\n<li>\n<p><strong>Gadget to be used by multiple people</strong> (examples above: two-way translation or music device) - The phone has become a very personal device over the years. If someone gets access to your phone unlocked they have access to who you are (important emails, personal photos, chat conversations, the apps you use and how do you spend your time, the songs you listen or books you read, even confidential documents). So, there are certain scenarios where you don't want to borrow your phone to someone to do something, since that requires trust that they won't see anything that is confidential. I think Rabbit r1 can go after this category because its a shiny gadget that doesn't really hold any personal information from the user, and this way allows the user to keep their phone in their pocket while using rabbit r1 for some tasks that the phone could also do but would require for others to have access to it.</p>\n</li>\n</ol>\n<br>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2024-04-28-rabbit-r1-there-is-hope_11.webp\"></p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"excited-about\">Excited about<a href=\"https://didierlopes.com/blog/rabbit-r1-there-is-hope#excited-about\" class=\"hash-link\" aria-label=\"Direct link to Excited about\" title=\"Direct link to Excited about\">​</a></h2>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"developer-ecosystem\">Developer Ecosystem<a href=\"https://didierlopes.com/blog/rabbit-r1-there-is-hope#developer-ecosystem\" class=\"hash-link\" aria-label=\"Direct link to Developer Ecosystem\" title=\"Direct link to Developer Ecosystem\">​</a></h3>\n<p>Apple became Apple not because of their revolutionary LCD screen without a keyboard, but because of the developer ecosystem they created. The iPhone became stickier over time, because there were more apps being built on top of it that users could easily tap into. It also allowed Apple to generate revenue from the monetization of these apps.</p>\n<p>I truly hope that this is the direction that Jesse and team want to take. If I were in their shoes, I would prioritize that over any other feature. Just allow developers to create apps (in this case functions) that the LAM can call to do something very specific.</p>\n<p>Instead of having their team working on all these features, create the foundational marketplace that allows developers to do so. Start by only allowing free apps and see what developers are building and what users are utilizing. Then move to allow developers to monetize and take a cut from it. And allow users to decide what apps are enabled within their devices and which ones aren't - show which apps are the most downloaded and used and link it to a user profile. Make it so that the user profile needs to be a rabbit r1 holder to avoid scams..</p>\n<p>A few examples: Someone building a Pokedex app for animals, you take r1 to the zoo and just take a picture of the animals with it, then you go home and look into your pokedex. Or a Pokedex for travel monuments. Or integrating OpenBB so I could do research on-the-go.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2024-04-28-rabbit-r1-there-is-hope_12.webp\"></p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"native-ai-phone\">Native AI-phone<a href=\"https://didierlopes.com/blog/rabbit-r1-there-is-hope#native-ai-phone\" class=\"hash-link\" aria-label=\"Direct link to Native AI-phone\" title=\"Direct link to Native AI-phone\">​</a></h3>\n<p><a href=\"https://us.nothing.tech/\" target=\"_blank\" rel=\"noopener noreferrer\">Nothing</a> has one of the best consumer tech brands out there. If the Apple ecosystem wasn't as sticky as it is today, I would buy one. Both Nothing and Rabbit are very unique brands, and I think a partnership between them could be a game-changer.</p>\n<p>I'm imagining a Native AI-phone built on Android with rabbit's LAM. So, in simple terms, it would be like Nothing Phone (2) but it would have an r1 button that you can use to interact with it through voice instead of fingers. The challenge would be combining the LAM from rabbit r1 to all the apps that Nothing Phone (2) provides - but I believe in a future where applications will be built not only thinking about how humans will utilize them but also LLMs - at least <a href=\"https://github.com/OpenBB-finance/openbb-agents\" target=\"_blank\" rel=\"noopener noreferrer\">we are doing that at OpenBB</a> with the <a href=\"https://github.com/OpenBB-finance/OpenBBTerminal\" target=\"_blank\" rel=\"noopener noreferrer\">OpenBB Platform</a>.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/rabbit-r1-there-is-hope",
            "title": "rabbit r1, there is hope",
            "summary": "I can see a future where people use rabbit r1 for very particular use cases where phone is suboptimal. For instance, when multiple people want to interact with said phone (e.g. selecting music at a party without having to give phone away) and that is not ideal due to personal information on phone, or when the phone isn't ideal because it has too many distractions and user wants to focus on doing something (e.g. practicing a presentation using recording session and then asking for feedback).",
            "date_modified": "2024-04-28T00:00:00.000Z",
            "tags": [
                "rabbit-r1",
                "tech",
                "review",
                "ai",
                "gadget"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/goh-analyst-the-ai-powered-financial-analyst-who-lives-on-slack",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2024-03-28-goh-analyst-the-ai-powered-financial-analyst-who-lives-on-slack_1.webp\"></p>\n<p>How I built a financial analyst that lives on Slack and has access to OpenBB.</p>\n<p>The open source code is available <a href=\"https://github.com/DidierRLopes/openbb-slack-agent\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"context\">Context<a href=\"https://didierlopes.com/blog/goh-analyst-the-ai-powered-financial-analyst-who-lives-on-slack#context\" class=\"hash-link\" aria-label=\"Direct link to Context\" title=\"Direct link to Context\">​</a></h2>\n<p>At OpenBB, we have the tradition of hosting an internal Creaton on the penultimate week of the year.</p>\n<p>The OpenBB Creaton is our creative Hackathon, where every team member picks a project to work on throughout the week and gets fully focused on it. The only rule is that it relies on OpenBB technology.</p>\n<p>It’s a way for us to get further contact with our technology, but it also allows us to create proofs-of-concept of products/features that we may invest in the feature. Think of it as an R&amp;D week.</p>\n<p>We do it then because our team members get the last week of the year as time off. So, if they want to present their project to the rest of the team in January, they can also use that time to wrap up.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"my-project\">My Project<a href=\"https://didierlopes.com/blog/goh-analyst-the-ai-powered-financial-analyst-who-lives-on-slack#my-project\" class=\"hash-link\" aria-label=\"Direct link to My Project\" title=\"Direct link to My Project\">​</a></h2>\n<p>At the Open Core Summit III, I presented a way of creating an AI-powered financial analyst capable of handling complex financial queries.</p>\n<p>I wrote more about this in this <a href=\"https://didierlopes.com/blog/creating-an-ai-powered-financial-analyst\">blog post</a>. This robust architecture can access 100+ financial datasets from OpenBB tools and reason about them. The code is open source here.</p>\n<p>I shared how our AI-powered financial analyst was able to answer</p>\n<blockquote>\n<p>“Check what TSLA peers are. From those, check which one has the highest market cap. Then, for the ticker that has the highest market cap, get the most recent price target estimate from an analyst, and tell me who it was and on what date the estimate was made.”</p>\n</blockquote>\n<br>\n<p>and</p>\n<blockquote>\n<p>“Perform a fundamentals financial analysis of AMZN using the most recently available data. What do you find that’s interesting?”</p>\n</blockquote>\n<br>\n<p>Since that was already working so well (watch the <a href=\"https://www.youtube.com/watch?v=A-43EKK2PhE&amp;embeds_referring_euri=https://openbb.co/blog/creating-an-ai-powered-financial-analyst&amp;source_ve_path=MjM4NTE\" target=\"_blank\" rel=\"noopener noreferrer\">presentation video here</a>), I wanted to bring these capabilities to Slack, show that this could be the future, and prove it would impact every analyst job.</p>\n<p>That’s when Goh Analyst was born.</p>\n<p align=\"center\"><img width=\"800\" src=\"https://didierlopes.com/blog/2024-03-28-goh-analyst-the-ai-powered-financial-analyst-who-lives-on-slack_2.webp\"></p>\n<p>Note: Goh Analyst together is GOHANalyst, which is why the image is Gohan from Dragon Ball with the OpenBB logo on his forehead.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"how-does-it-work\">How does it work?<a href=\"https://didierlopes.com/blog/goh-analyst-the-ai-powered-financial-analyst-who-lives-on-slack#how-does-it-work\" class=\"hash-link\" aria-label=\"Direct link to How does it work?\" title=\"Direct link to How does it work?\">​</a></h2>\n<p>To get started, you can see the <a href=\"https://github.com/DidierRLopes/openbb-slack-agent/tree/main\" target=\"_blank\" rel=\"noopener noreferrer\">open-source repository and instructions</a>.</p>\n<p>First, I forked the <a href=\"https://github.com/OpenBB-finance/openbb-agents\" target=\"_blank\" rel=\"noopener noreferrer\">open-source code of the OpenBB agents repository</a> that we have been using for R&amp;D. This repository contains all the code for the OpenBB agent and has access to 100+ financial datasets.</p>\n<p>Then, I modified it to my needs:</p>\n<p>Created the Slack bot interface</p>\n<p>When a Slack message mentions @Gohanalyst this workflow gets triggered</p>\n<p>When the Slack message contains the word “OpenBB”, I send that message through the OpenBB agent since the assumption is that data retrieval will be necessary. Otherwise, it goes straight through OpenAI.</p>\n<p>In a nutshell, this is what the architecture looks like:</p>\n<p align=\"center\"><img width=\"800\" src=\"https://didierlopes.com/blog/2024-03-28-goh-analyst-the-ai-powered-financial-analyst-who-lives-on-slack_3.webp\"></p>\n<p>I made Goh Analyst slightly sarcastic to make it a bit more fun. This makes interacting in a public channel somewhat more human and exciting. It can handle simple financial questions, retrieve data using OpenBB tools, or even answer more complex reasoning questions.</p>\n<p align=\"center\"><img width=\"800\" src=\"https://didierlopes.com/blog/2024-03-28-goh-analyst-the-ai-powered-financial-analyst-who-lives-on-slack_4.webp\"></p>\n<p align=\"center\"><img width=\"800\" src=\"https://didierlopes.com/blog/2024-03-28-goh-analyst-the-ai-powered-financial-analyst-who-lives-on-slack_5.webp\"></p>\n<p>Now imagine that every organization has an analyst on their Slack to help make decisions.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"whats-next\">What's next<a href=\"https://didierlopes.com/blog/goh-analyst-the-ai-powered-financial-analyst-who-lives-on-slack#whats-next\" class=\"hash-link\" aria-label=\"Direct link to What's next\" title=\"Direct link to What's next\">​</a></h2>\n<p>As I mentioned earlier, one of the advantages we get from OpenBB Creaton is that we test our products and give feedback to the team on what went well or less well. After working on this project, this is what I shared with the team:</p>\n<p align=\"center\"><img width=\"800\" src=\"https://didierlopes.com/blog/2024-03-28-goh-analyst-the-ai-powered-financial-analyst-who-lives-on-slack_6.webp\"></p>\n<p>Exciting times we live in. If you want to leverage AI within your financial firm, we can help you 🤝</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/goh-analyst-the-ai-powered-financial-analyst-who-lives-on-slack",
            "title": "Goh Analyst - The AI-powered financial analyst who lives on Slack",
            "summary": "How I built a financial analyst that lives on Slack and has access to OpenBB.",
            "date_modified": "2024-03-26T00:00:00.000Z",
            "tags": [
                "learning",
                "experience",
                "growth",
                "moving",
                "london",
                "bay",
                "us",
                "travel",
                "startup",
                "nyc"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/moving-countries-and-starting-a-company-aint-so-different",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2024-03-28-goh-analyst-the-ai-powered-financial-analyst-who-lives-on-slack.webp\"></p>\n<p>I have started a company. I have moved countries. It turns out that there's a lot in common between these.</p>\n<br>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>Recently, I wrote a blogpost about the <a href=\"https://didierlopes.com/blog/moving-from-london-to-the-bay-area-and-what-changed\">difference in culture between London and San Francisco</a>. I convinced my wife and dogs, packed our bags, and didn't look back. After all, I would live in the city with the highest density of builders per capita.</p>\n<p><strong>But why?</strong></p>\n<p>Most of my friends and family didn't understand why I would leave London. I liked the city, I enjoyed my lifestyle, I had friends, I played football with the same group every week, had dinner at the same restaurants, was close to family, and wouldn't be able to save money.</p>\n<p>Logically speaking, this move didn't make any sense. No one really told me that I was doing the right thing, but internally, I knew I had to.</p>\n<p>I believe this isn't so different from creating a startup. This blog post will explain what they have in common and why I did it.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"creating-a-startup--deciding-to-leave-your-country\">Creating a startup / Deciding to leave your country<a href=\"https://didierlopes.com/blog/moving-countries-and-starting-a-company-aint-so-different#creating-a-startup--deciding-to-leave-your-country\" class=\"hash-link\" aria-label=\"Direct link to Creating a startup / Deciding to leave your country\" title=\"Direct link to Creating a startup / Deciding to leave your country\">​</a></h2>\n<p><a href=\"http://eladgil.com/\" target=\"_blank\" rel=\"noopener noreferrer\">Elad Gil</a> wrote a really good <a href=\"https://blog.eladgil.com/p/startups-are-an-act-of-desperation\" target=\"_blank\" rel=\"noopener noreferrer\">article</a> on how creating a startup is an act of desperation. I believe that post could be equally applicable to moving countries, so I will list the same points used by Elad in the context of moving countries and provide examples. Most of the time, the person moving countries has a mix of the below bullet points.</p>\n<blockquote>\n<p><strong>Career desperation.</strong> Startups allow people early or stuck in their careers to jump a few steps ahead.</p>\n</blockquote>\n<br>\n<p>This applies equally to moving, and is why I left Portugal to pursue an MSc at Imperial College London.</p>\n<blockquote>\n<p><strong>Financial desperation.</strong> If successful, a startup will also leapfrog you financially.</p>\n</blockquote>\n<br>\n<p>This is the biggest motivation for people to move countries. This is why I was born in Switzerland, even though my parents are Portuguese. Having blue-collar jobs, they emigrated to a country with a better economy to provide my brother and me with a better life.</p>\n<blockquote>\n<p><strong>Product or mission desperation.</strong> The other reason startups often exist is that the founders are desperate for a product to exist in the world.</p>\n</blockquote>\n<br>\n<p>In this case, it's the equivalent of hearing about Silicon Valley in documentaries or watching Steve Jobs presenting the iPhone in 2007. You cannot ignore that as an engineer, so you are desperate to move to be part of that tech scene.</p>\n<blockquote>\n<p><strong>Desperation to do something big or important, and to avoid wasted time.</strong> Some people want to \"make a dent in the universe\" and are motivated by doing something useful with their lives.</p>\n</blockquote>\n<br>\n<p>This is what the \"American dream\" is all about. People moved to the US to do something bigger than themselves and achieve the promised dream.</p>\n<blockquote>\n<p><strong>Revenge vs the Arena</strong></p>\n</blockquote>\n<br>\n<p>The equivalent to this is when someone returns to their home country after several years outside with more wealth and/or experience.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"growing-a-startup--living-abroad\">Growing a startup / Living abroad<a href=\"https://didierlopes.com/blog/moving-countries-and-starting-a-company-aint-so-different#growing-a-startup--living-abroad\" class=\"hash-link\" aria-label=\"Direct link to Growing a startup / Living abroad\" title=\"Direct link to Growing a startup / Living abroad\">​</a></h2>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"mission-and-vision\">Mission and Vision<a href=\"https://didierlopes.com/blog/moving-countries-and-starting-a-company-aint-so-different#mission-and-vision\" class=\"hash-link\" aria-label=\"Direct link to Mission and Vision\" title=\"Direct link to Mission and Vision\">​</a></h3>\n<p>When creating a company, you must have a clear mission and vision. This allows you to create a community/team that will be with you for the long run. Similarly, when moving countries, it's essential to have a well-defined goal. This doesn't mean that the goal cannot change; after all, companies pivot. However, you need to have a strategy that you follow until you don't.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"risk-and-uncertainty\">Risk and Uncertainty<a href=\"https://didierlopes.com/blog/moving-countries-and-starting-a-company-aint-so-different#risk-and-uncertainty\" class=\"hash-link\" aria-label=\"Direct link to Risk and Uncertainty\" title=\"Direct link to Risk and Uncertainty\">​</a></h3>\n<p>Startups and moving to a new country both involve stepping into the unknown. Entrepreneurs often take financial and personal risks, while those moving countries leave behind familiar surroundings, support systems, and sometimes even their careers. Uncertainty becomes a constant companion, demanding adaptability, problem-solving skills, and the ability to embrace change with open arms.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"cultural-integration-and-networking\">Cultural Integration and Networking<a href=\"https://didierlopes.com/blog/moving-countries-and-starting-a-company-aint-so-different#cultural-integration-and-networking\" class=\"hash-link\" aria-label=\"Direct link to Cultural Integration and Networking\" title=\"Direct link to Cultural Integration and Networking\">​</a></h3>\n<p>Building a successful startup requires networking, forming strategic partnerships, and understanding the market. Similarly, when moving countries, one must navigate cultural differences, learn new languages, and establish a network of contacts. Expanding social circles, building relationships, and immersing oneself in the local culture contribute to personal growth and enhance professional opportunities, just like in the startup world.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"resilience-and-persistence\">Resilience and Persistence<a href=\"https://didierlopes.com/blog/moving-countries-and-starting-a-company-aint-so-different#resilience-and-persistence\" class=\"hash-link\" aria-label=\"Direct link to Resilience and Persistence\" title=\"Direct link to Resilience and Persistence\">​</a></h3>\n<p>Building a startup and moving countries demands unwavering resilience and persistence in facing challenges. Startups encounter setbacks, pivots, and failures, but successful entrepreneurs persist and learn from their experiences. Similarly, moving countries can bring unexpected hurdles, such as language barriers, difficulties making friends, challenges adapting to a new culture, or not finding a routine. Embracing these challenges with determination and adaptability paves the way for growth and achievement.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"learning-and-growth\">Learning and Growth<a href=\"https://didierlopes.com/blog/moving-countries-and-starting-a-company-aint-so-different#learning-and-growth\" class=\"hash-link\" aria-label=\"Direct link to Learning and Growth\" title=\"Direct link to Learning and Growth\">​</a></h3>\n<p>Startups and moving countries are transformative experiences that offer immense personal and professional growth opportunities. Entrepreneurs continuously learn from their successes and failures in the startup world, refining their strategies and acquiring new skills. Likewise, moving countries provides a unique chance to learn about different cultures, broaden perspectives, and develop resilience, patience, and empathy. Both experiences foster personal development and shape individuals into more well-rounded and adaptable individuals.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"why-did-i-do-it\">Why did I do it?<a href=\"https://didierlopes.com/blog/moving-countries-and-starting-a-company-aint-so-different#why-did-i-do-it\" class=\"hash-link\" aria-label=\"Direct link to Why did I do it?\" title=\"Direct link to Why did I do it?\">​</a></h2>\n<p>The reason why I started OpenBB and also moved country is a combination of 2 factors:</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"product-or-mission-desperation\">Product or mission desperation.<a href=\"https://didierlopes.com/blog/moving-countries-and-starting-a-company-aint-so-different#product-or-mission-desperation\" class=\"hash-link\" aria-label=\"Direct link to Product or mission desperation.\" title=\"Direct link to Product or mission desperation.\">​</a></h3>\n<p>On a startup level, I have experienced the need for an open-source investment research platform. That's why I wanted to create this platform, which was yet to exist. I think it wouldn't be possible if I didn't dedicate my time to it. This is why OpenBB's success is so important-it will enable millions of investors to have better access to data and better understand the financial market.</p>\n<p>Growing up as an engineer fascinated by tech and innovation, the US has always been home to the biggest companies and hottest products. I've always been attracted to Silicon Valley, but before OpenBB, I never had the chance to. The first job I applied to after finishing university was Waymo in CA, but they didn't sponsor VISAs for that role.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"desperation-to-do-something-big-or-important\">Desperation to do something big or important.<a href=\"https://didierlopes.com/blog/moving-countries-and-starting-a-company-aint-so-different#desperation-to-do-something-big-or-important\" class=\"hash-link\" aria-label=\"Direct link to Desperation to do something big or important.\" title=\"Direct link to Desperation to do something big or important.\">​</a></h3>\n<p>On a startup level, I want to work on something bigger than myself. I want to solve a problem that no one has solved before and build something useful for millions of people that can withstand time.</p>\n<p>I will do whatever it takes to build the first truly open-source investment research platform. Moving to SF increased my network opportunities with other entrepreneurs and builders from whom I can learn. I want to be fully immersed in this ecosystem and give it my all to do everything possible to help OpenBB succeed as a company, regardless of the outcome.</p>\n<p>Note: A few weeks ago, I moved to NYC because I truly believe living here would increase the chances of OpenBB's success compared to living in SF.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/moving-countries-and-starting-a-company-aint-so-different",
            "title": "Moving countries and starting a company ain't so different",
            "summary": "I have started a company. I have moved countries. It turns out that there's a lot in common between these.",
            "date_modified": "2024-03-24T00:00:00.000Z",
            "tags": [
                "startup",
                "founder-story",
                "relocation",
                "personal-growth",
                "career-path",
                "risk-taking",
                "ambition",
                "resilience",
                "life-lessons"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/moving-from-london-to-the-bay-area-and-what-changed",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2024-03-02-moving-from-london-to-the-bay-area-and-what-changed.webp\"></p>\n<p>The culture shock from moving to the Bay Area from London.</p>\n<br>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>A few months ago, I wrote a blogpost about what was needed in order for my wife and our 2 dogs to move to the Bay Area from London. You can check that blog post <a href=\"https://didierlopes.com/blog/leaving-london-to-live-in-san-francisco/\">here</a>.</p>\n<p>Since then, I’ve had some people asking me after living in the Bay for 1 year, what are the biggest differences I’ve experienced in terms of lifestyle &amp; culture.</p>\n<p>I will write a section below for each of the major topics I experienced. Note that this is based on my experience, and you may disagree/have different opinions than me on some of these - which are very welcome.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"living-costs\">Living costs<a href=\"https://didierlopes.com/blog/moving-from-london-to-the-bay-area-and-what-changed#living-costs\" class=\"hash-link\" aria-label=\"Direct link to Living costs\" title=\"Direct link to Living costs\">​</a></h2>\n<p>Back in 2016 when I was at university, in Portugal, I used to pay 200 euros/month to live in an apartment with a roommate. My university cost was 800 euros/year and my parents gave me a monthly allowance of 300 euros/month to pay for food and anything else. I didn’t do many activities and would rarely go out, so I was able to live comfortably on that.</p>\n<p>Once I moved to London (in 2017) to pursue a MSc. at Imperial College I was paying 1.6k £/month for a studio in Earl’s Court. This was walking distance from Imperial (didn’t have to pay for transportation) and was cheaper than the accommodations that the university offered. The university was no longer 800 euros/year, it cost £11k for the entire MSc (1 year).</p>\n<p>So there was a shock that I experienced in terms of living costs from Lisbon to London.</p>\n<p>Once I decided to move to the Bay Area (2023) I knew that the living costs were going to be higher, but in my head “how higher can these be?”.</p>\n<p>Oh boy.</p>\n<p>Apparently, a lot.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"shopping\">Shopping<a href=\"https://didierlopes.com/blog/moving-from-london-to-the-bay-area-and-what-changed#shopping\" class=\"hash-link\" aria-label=\"Direct link to Shopping\" title=\"Direct link to Shopping\">​</a></h3>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2024-03-02-moving-from-london-to-the-bay-area-and-what-changed_1.webp\"></p>\n<p>This was the first shopping trip I had in the Bay (Whole foods is the equivalent to Waitrose in London, I often still confuse them and my wife finds it funny - anyway, they call it whole paycheck here bc $$$). These 10 items cost me $69.34. I couldn’t believe it.</p>\n<p>Costco is arguably my favorite shop. It’s like a better IKEA. We would spend at least 2 hours shopping but we would get supplies for 3 weeks, the famous hot dog/pizza combo and put gas in the car. The membership (120$/year) pays itself really fast at Costco. The main downside is that since we were only 2 and I hate throwing food out, it happened a few times that I had to adapt my meals to make sure no food would go to waste. E.g. Eat a guacamole pack a day since the smaller pack brings 24 and it there were 24 days until the expiry date.</p>\n<p>PS: I like Costco so much that I always took the friends/family who visited to it, as if it was an attraction. Sometimes we would even go directly to Costco from the airport, to breathe in Costco and all its magnificence upon arrival <!-- -->:D</p>\n<p align=\"center\" class=\"flex items-center gap-2 justify-center\"><img width=\"300\" src=\"https://didierlopes.com/blog/2024-03-02-moving-from-london-to-the-bay-area-and-what-changed_2.webp\"><img width=\"300\" src=\"https://didierlopes.com/blog/2024-03-02-moving-from-london-to-the-bay-area-and-what-changed_3.webp\"></p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"apartment\">Apartment<a href=\"https://didierlopes.com/blog/moving-from-london-to-the-bay-area-and-what-changed#apartment\" class=\"hash-link\" aria-label=\"Direct link to Apartment\" title=\"Direct link to Apartment\">​</a></h3>\n<p>Since I went to the US with the sole purpose of working hard and making OpenBB successful, I ended up picking a nice apartment in San Mateo - given that we spend 90% of our time at home. Our monthly rent for a 2-bedroom flat was 4.4k $/month with everything included (including both dogs rent, lol).</p>\n<p>The apartment had a small gym, a common pool &amp; bbq area and an outdoor hot tub. But more importantly, it was located right by 101, walking distance from Peets &amp; Starbucks and very pet friendly. In addition, I was 40m from SF, 10m from the airport and 20m from Palo Alto. This meant that we were in a very calm area whilst being close to the most important hubs.</p>\n<p>The common pool and BBQ area (+ the sunny weather) were insane, sometimes I wish I had spent more time there. But I guess you tend to value things more when you don’t have them :)</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2024-03-02-moving-from-london-to-the-bay-area-and-what-changed_4.webp\"></p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"tipping-culture\">Tipping culture<a href=\"https://didierlopes.com/blog/moving-from-london-to-the-bay-area-and-what-changed#tipping-culture\" class=\"hash-link\" aria-label=\"Direct link to Tipping culture\" title=\"Direct link to Tipping culture\">​</a></h3>\n<p>In Europe, I very very rarely tipped. Not just me, but all people I know. It’s just not part of our culture. Everything is factored in. Even in London, most restaurants will have a “service charge” which is kind of a tip BUT it’s included in the bill and so you don’t need to think about how much you are going to tip.</p>\n<p>In the US, if you don’t tip - people will judge you. The system is done in a way that tipping is not a “should” but closer to a “must”. Workers rely on your tips when thinking about their total compensation. And now I understand why my friends who work in restaurants/cafes enjoy Americans so much, it’s because they bring their tipping culture to Europe and so that extra money is very meaningful for European folks.</p>\n<p>Some rules that I follow:</p>\n<ul>\n<li>If I go to a coffee shop and just do takeaway, I don’t tip. If I sit down in a table, then I tip between 15-20%.</li>\n<li>When in a restaurant, I always tip. But the percentage varies based on the quality of the service and food. If I didn’t like it, I still tip 10%. If I really enjoy it then I tip 20%. If it was just good, I do 15%. This is a rule of thumb. In practice, I do this but then round to a multiple of $5 because yes (this is the equivalent to my wife not allowing odd numbers as the TV volume).</li>\n</ul>\n<p>The best way to get used to this is to just internally assume that 20% extra cost on whatever you are seeing on the menu. If a burger + drink costs $30, assume it will be $36 after taxes and tip.</p>\n<p>Note that in restaurants they expect you to leave your credit card on the top of the bill. This is so they can “freeze” the bill and once they bring the receipt back they will wait for you to add the amount for the tip (+ total). Once you fill this and sign (in theory, the signing is mandatory) - only then they will be able to withdraw the bill amount + the tip.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2024-03-02-moving-from-london-to-the-bay-area-and-what-changed_5.webp\"></p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"sports\">Sports<a href=\"https://didierlopes.com/blog/moving-from-london-to-the-bay-area-and-what-changed#sports\" class=\"hash-link\" aria-label=\"Direct link to Sports\" title=\"Direct link to Sports\">​</a></h2>\n<p>Growing up in Portugal I used to watch every Benfica game and then in high school you would talk about the games you watched during the weekend. There was no other sport, it was a binary - either you are a soccer fan or you don’t watch any sports at all. When I moved to London, this changed slightly, there were people that liked other sports but Soccer was still the main sport by a very big margin. People would fill up a pub to watch Soccer only - maybe the other sport that came closest was Cricket.</p>\n<p>In the US, people don’t really care about Soccer. It feels like it’s a sport that kids do, but adults don’t really talk about it or watch it. They know about Messi/Ronaldo, but aren’t really fans. On the other hand, American football, Basketball and Baseball are very big. Aquatic pole also seems to be popular in the Bay Area.</p>\n<p>I remember when we got the apartment, I was walking my dogs and there was a soccer pitch nearby. I was super happy because I thought that I could do what I used to do in London and just show up to the ground on the weekend and do a pick-up play with random folks. Unfortunately, after several attempts of walking nearby I realized that the pitch was only used for kids to play soccer and never adults. In London, on a sunny day, it’s hard (maybe impossible?) to find a soccer field empty.</p>\n<p align=\"center\" class=\"flex items-center gap-2 justify-center\"><img width=\"300\" src=\"https://didierlopes.com/blog/2024-03-02-moving-from-london-to-the-bay-area-and-what-changed_6.webp\"><img width=\"300\" src=\"https://didierlopes.com/blog/2024-03-02-moving-from-london-to-the-bay-area-and-what-changed_7.webp\"></p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"college-sports\">College sports<a href=\"https://didierlopes.com/blog/moving-from-london-to-the-bay-area-and-what-changed#college-sports\" class=\"hash-link\" aria-label=\"Direct link to College sports\" title=\"Direct link to College sports\">​</a></h3>\n<p>While in Europe in general, no one cares about college sports. The reality in the US is completely different. Not only do they fill their stadiums with 50k+ people, but these games bring a TON of money. People will literally sit outside the stadium in the morning and wait for the time of the match. It’s called tailgating.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2024-03-02-moving-from-london-to-the-bay-area-and-what-changed_8.webp\"></p>\n<p>I’ve noticed that some people don’t even go to the stadium, they just sit outside the stadium watching the game in the car park on their TV and drinking. I still don’t fully get why you would do that, but I guess it’s a tradition.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2024-03-02-moving-from-london-to-the-bay-area-and-what-changed_9.webp\"></p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"working-culture\">Working Culture<a href=\"https://didierlopes.com/blog/moving-from-london-to-the-bay-area-and-what-changed#working-culture\" class=\"hash-link\" aria-label=\"Direct link to Working Culture\" title=\"Direct link to Working Culture\">​</a></h2>\n<p>My plan was to live in the US for the duration of my visa (O-1) and then return after 3 years. But the working culture is the reason why I hope to stay for longer. Most people you will meet in the Bay work very hard. They don’t finish the day at 5/6pm but do long hours to get shit done. What motivates them is building the future and being part of something bigger than themselves.</p>\n<p>In London, I felt like the culture was very strong towards finishing your working day and going to the pub at 5/6pm - get drunk. And then repeat. Before London I didn’t drink alcohol, and in London I started drinking sometimes to socialize. In the Bay I feel like there isn’t an expectation that everyone wants to drink, and people leave events early because they want to head home to work on something - which is something I used to do back in London.</p>\n<p>I also feel like in the Bay Area, when you go to events you can talk about what you are working on without people judging you for bringing “work” into the conversation. And I tend to find these conversations more interesting. In London, there’s less emphasis in tech, and the interests tend to be a bit broader: music, arts, history, etc..</p>\n<p>While people say that London is a big hub for startups &amp; founders, I didn’t find this to be the case. In the Bay Area, the likelihood of you encountering someone on the street and them working at a startup (most of the time their own) is really high. You can even feel the strength of this tech community on Twitter, whereas that doesn’t exist (AFAIK) in London.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2024-03-02-moving-from-london-to-the-bay-area-and-what-changed_10.webp\"></p><p>Elad Gil fireside with Satya Nadella at Stripe's HQ</p><p></p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"equity-as-part-of-compensation-package\">Equity as part of compensation package<a href=\"https://didierlopes.com/blog/moving-from-london-to-the-bay-area-and-what-changed#equity-as-part-of-compensation-package\" class=\"hash-link\" aria-label=\"Direct link to Equity as part of compensation package\" title=\"Direct link to Equity as part of compensation package\">​</a></h3>\n<p>Most European startups do not offer any equity. In the Bay Area, all startups offer equity. The earlier you join (higher risk) the more meaningful the options you get are. One of the reasons this works is because US employees are, in general, hard-working and will go the long way for their company. So this makes it so that incentives are aligned, and employees want to work harder because that equity can become much more meaningful than their base salary (potentially life-changing).</p>\n<p>One of the reasons this works so well is that pretty much every US person knows someone in firsthand who made f-u money by selling their shares in secondaries, or has at least heard stories about this. While I was in the UK, before starting OpenBB, I didn’t hear about this once. Also because companies have no interest in offering you equity if they don’t have to.</p>\n<p>E.g. at my previous startup I used to stay working late into the night, because in my perspective this would increase the startup's chances of success. However, I had no equity. So this meant that if the startup was wildly successful, I would have no direct gains from it and the company would not owe me anything. Offering equity through a typical 4-year vesting schedule (with 1-year cliff) provides the perfect type of alignment.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"holidays\">Holidays<a href=\"https://didierlopes.com/blog/moving-from-london-to-the-bay-area-and-what-changed#holidays\" class=\"hash-link\" aria-label=\"Direct link to Holidays\" title=\"Direct link to Holidays\">​</a></h3>\n<p>The amount of holidays is a good example that demonstrates the hard-working culture that so well characterizes the US. In the US they are used to having 2-weeks off in a full calendar year. In London, most companies offer at least 4-weeks, which is effectively 2x the number of holidays.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"driving-culture\">Driving culture<a href=\"https://didierlopes.com/blog/moving-from-london-to-the-bay-area-and-what-changed#driving-culture\" class=\"hash-link\" aria-label=\"Direct link to Driving culture\" title=\"Direct link to Driving culture\">​</a></h2>\n<p>The London underground works impressively, I lived there for 5 years and never once even considered owning a car.</p>\n<p>I thought I could do the same in the US and people were being dramatic. That thought lasted maybe 2 days?</p>\n<p>On the first day I had to go to Fedex which was a 15-20m walk, and when I told the apartment administrator that I was going to walk there she looked at me like I was crazy and said “you need to take your car”. After walking there I understood what she meant and that unless you are in a city, the pedestrian sidewalks/roads just aren’t prepared for pedestrians.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"differences\">Differences<a href=\"https://didierlopes.com/blog/moving-from-london-to-the-bay-area-and-what-changed#differences\" class=\"hash-link\" aria-label=\"Direct link to Differences\" title=\"Direct link to Differences\">​</a></h3>\n<ul>\n<li>You drive on the right (x2) side of the road. Since I didn’t drive in the UK, this was very easy for me as I’m used to driving in Portugal where we also drive on the right side of the road.</li>\n<li>In the UK (or Europe, in general) having more than 3 lanes on the highway is atypical. In the US, having 6 lanes it’s considered normal. Sometimes it’s tricky and you can’t be in the most right side because the 2 right lanes may both exit and thus you need to hop over 2 lanes to keep on the same route. This mistake can be costly.</li>\n<li>There are very very few roundabouts in the Bay. There are a LOT of intersections. I like it less (not because I think it’s slower) but because it’s more “boring” to wait for the green light and from my point of view, people are more likely to grab their phone during that time because they don’t need to pay as much attention, at least compared to a roundabout where you are waiting for an opening to keep moving. (there are so few roundabouts that the first time I saw one I took a picture to share with my wife)</li>\n<li>There’s a “Right on Red” policy. This means that if you are at an intersection and it’s red for you to proceed if there’s no incoming car from the left side you can turn right on the red. I like this because it allows for traffic to flow better. My wife doesn’t like it because as a pedestrian sometimes cars start accelerating and don’t respect pedestrian as much. Nonetheless, I love to make this joke when people from Europe visit, where I say that I’m going to pass a red and they are shocked when they see me turning right on a red light.</li>\n<li>In the Bay they have FastTrack which allows people to pay to use the most-left lane and avoid traffic. Although this is capitalist I like it because if I’m in a rush I can pay a few dollars to avoid the congestion - it’s a type of SaaS - Speed as a Service 😄</li>\n</ul>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"waymo\">Waymo<a href=\"https://didierlopes.com/blog/moving-from-london-to-the-bay-area-and-what-changed#waymo\" class=\"hash-link\" aria-label=\"Direct link to Waymo\" title=\"Direct link to Waymo\">​</a></h3>\n<p>Waymo, a self-driving car division that started off Google, was the first startup I applied to when I finished university. I have been bullish on self-driving cars since university - my dissertation was on that topic and I had to propose it myself, since there were no proposals for such. So seeing Waymo operating in SF was mind-blowing to me.</p>\n<p>Autonomous cars are a matter of time - and SF (and the Bay Area) being the city where Waymo starts operating, shows a lot about how progressive this city is. I recommend everyone to try one out.</p>\n<p>My dad, someone who was born and raised in a small town in Portugal, and who understands very little about technology seeing this was something. Him seated in the passenger’s seat for the full 16 min drive recording a wheel with no driver and ending the journey telling me “I never thought I would see this in my life, thank you” is something that no amount of money in this world could buy.</p>\n<p align=\"center\" class=\"flex items-center gap-2 justify-center\"><img width=\"300\" src=\"https://didierlopes.com/blog/2024-03-02-moving-from-london-to-the-bay-area-and-what-changed_11.webp\"><img width=\"300\" src=\"https://didierlopes.com/blog/2024-03-02-moving-from-london-to-the-bay-area-and-what-changed_12.webp\"></p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"driving-license\">Driving license<a href=\"https://didierlopes.com/blog/moving-from-london-to-the-bay-area-and-what-changed#driving-license\" class=\"hash-link\" aria-label=\"Direct link to Driving license\" title=\"Direct link to Driving license\">​</a></h3>\n<p>Even though I have a Portuguese driving license since I was 18. That’s only accepted for 10 days or so - and if you have an international driving license for it to work for longer (I didn’t go this route). So I had to apply for a California Driving License (CDL) which meant taking a written exam and doing a driving test.</p>\n<p>The written exam was actually fairly easy compared to the one I had in Portugal. In the Bay, the test consists of 36 multiple-choice questions, and you are allowed to fail up to 6 questions.  In Portugal I had 30 multiple-choice questions and could only fail up to 3.</p>\n<p>I found the written exam to be easy after doing multiple practice tests online. Most of the questions ended up being somewhat similar to the ones I had practiced the day before.</p>\n<p>Doing the written exam was very different though. In Portugal we did it in a closed room with someone watching us and everyone else in silence. In the Bay Area I did it in a corner of the DMV with a lot of background noise behind me. I had to use both my hands to cover my ears to be able to focus, which was annoying.</p>\n<p>The driving exam is much easier than the one I did in Portugal. It lasted for maybe 20-25 minutes and it was just around the DMV. When doing it in Portugal, the test lasts 40 minutes and includes: parallel parking, reversing while tracking a curb (without touching it), stopping in a hill (harder when driving with a stick), roundabout and highway.</p>\n<p>Also, the DMV is as bad as they say it is. This movie scene is pretty accurate:</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2024-03-02-moving-from-london-to-the-bay-area-and-what-changed_13.webp\"></p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"cards\">Cards<a href=\"https://didierlopes.com/blog/moving-from-london-to-the-bay-area-and-what-changed#cards\" class=\"hash-link\" aria-label=\"Direct link to Cards\" title=\"Direct link to Cards\">​</a></h2>\n<p>In the US, as in the UK, the driving license acts as citizen card. Even if you don’t drive it’s worth getting your drivers license since everywhere you go that is used for you to prove who you are.</p>\n<p>When doing anything official in the UK, you get asked about your passport (and the passport number). That ID is all they need to recognize who you are. In the US you have a Social Security Number (SSN) which is this super-confidential number that you are meant to keep secret, yet they keep asking you about it when you rent an apartment, set up a phone plan, go to the doctor, buy a car, … It’s a weird concept. The difference is that in the UK if someone gets your passport number, nothing really happens. In the US if someone gets your SSN, it can be used to commit fraud, open new credit and bank accounts, obtain employment, and access medical care or other benefits.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"debit-vs-credit-card\">Debit vs credit card<a href=\"https://didierlopes.com/blog/moving-from-london-to-the-bay-area-and-what-changed#debit-vs-credit-card\" class=\"hash-link\" aria-label=\"Direct link to Debit vs credit card\" title=\"Direct link to Debit vs credit card\">​</a></h3>\n<p>In Portugal and the UK, I only had a Debit card which had access to all the cash in the bank. When moving to the Bay Area, everyone told me to get a credit card and leave the debit card at home. There are a lot of scams in the US, and having a credit card is safer since banks limit the withdrawal amounts based on your credit score and will protect in case of theft.</p>\n<p>In the UK, there isn’t a concept of a credit score - at least publicly. Banks will have something like that based on how on time you pay for things, but it’s only used internally for loans or others. In the US, everything revolves around your credit score. The amount of money you can withdraw from your credit card, the loans you get, the apartments you can rent, … so it’s important to pay everything on time and avoid debt.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"employment\">Employment<a href=\"https://didierlopes.com/blog/moving-from-london-to-the-bay-area-and-what-changed#employment\" class=\"hash-link\" aria-label=\"Direct link to Employment\" title=\"Direct link to Employment\">​</a></h2>\n<p>Employment in the US is very different from the one in the UK.</p>\n<p>In the UK, you get paid a value at the end of the month that corresponds to the value you take home and the employer handles both your Income taxes and the National insurance (which goes to the NHS).</p>\n<p>In the US, you need to handle your taxes at the end of a fiscal year. There are multiple taxes applied and hence it’s not as simple as the tax system that exists in the UK.</p>\n<p>In addition, there isn’t a public “free” NHS (healthcare) in the United States. As an individual, you need to select the plan you are interested in (based on a few choices that your employer offers you). Hence you need to consider not only what the monthly premium entails, but how the deductible works - and as weird as it sounds you need to “estimate” your likelihood of getting into an accident to select something that works for you. This is hard to grasp coming from a country where there’s “free” healthcare and everyone has access to the same services.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"others\">Others<a href=\"https://didierlopes.com/blog/moving-from-london-to-the-bay-area-and-what-changed#others\" class=\"hash-link\" aria-label=\"Direct link to Others\" title=\"Direct link to Others\">​</a></h2>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"student-debt\">Student debt<a href=\"https://didierlopes.com/blog/moving-from-london-to-the-bay-area-and-what-changed#student-debt\" class=\"hash-link\" aria-label=\"Direct link to Student debt\" title=\"Direct link to Student debt\">​</a></h3>\n<p>In Portugal, the concept of student debt doesn’t really exist. In general, parents pay their kids' tuition. This is possible because the tuition costs for public universities aren’t very high.</p>\n<p>In the UK, students tend to have student debt since university costs can be rather expensive (e.g. around 10k pounds/year).</p>\n<p>In the US, student debt is much higher. We are talking about starting a career with 300k in student loans, which is absolutely wild.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"phone-plan\">Phone plan<a href=\"https://didierlopes.com/blog/moving-from-london-to-the-bay-area-and-what-changed#phone-plan\" class=\"hash-link\" aria-label=\"Direct link to Phone plan\" title=\"Direct link to Phone plan\">​</a></h3>\n<p>While I was paying around 8 pounds/month for my UK phone plan with unlimited data. For a similar plan in the US, the cost is around 70 $/month. A funny story about this is when I bought my phone plan, they told me that the cost was 70$ for their cheapest plan and I thought they meant yearly. When they told me it was monthly, I had to call my co-founder to make sure this wasn’t a rip-off. To which he said: “Welcome to the US”.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"guns--alcohol\">Guns &amp; Alcohol<a href=\"https://didierlopes.com/blog/moving-from-london-to-the-bay-area-and-what-changed#guns--alcohol\" class=\"hash-link\" aria-label=\"Direct link to Guns &amp; Alcohol\" title=\"Direct link to Guns &amp; Alcohol\">​</a></h3>\n<p>In the UK (and Europe in general), it’s illegal to own a gun and you can start drinking at 18 years old. In the US, you can buy a gun as soon as you are 18 but aren’t allowed to drink until 21.</p>\n<p>And also, Kinder Surprise is illegal in the US because of the toy that comes inside. So you can’t buy a chocolate with a toy inside because you can choke on it, but can go to the store to buy a gun.</p>\n<p align=\"center\" class=\"flex items-center gap-2 justify-center\"><img width=\"300\" src=\"https://didierlopes.com/blog/2024-03-02-moving-from-london-to-the-bay-area-and-what-changed_14.webp\"><img width=\"300\" src=\"https://didierlopes.com/blog/2024-03-02-moving-from-london-to-the-bay-area-and-what-changed_15.webp\"></p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"dog-parks\">Dog Parks<a href=\"https://didierlopes.com/blog/moving-from-london-to-the-bay-area-and-what-changed#dog-parks\" class=\"hash-link\" aria-label=\"Direct link to Dog Parks\" title=\"Direct link to Dog Parks\">​</a></h3>\n<p>One of my all-time favorite things in the US and that Europe in general should learn from. The US has a LOT of dog parks. These are spaces that are gated where people bring their dogs for them to play together. These spaces come fully prepared with water, bags, cleaning kits and even seats. I’ve seen friends hang out at the park while their dogs are having fun playing with other dogs. These parks usually also have 2 areas, one for smaller and one for larger dogs - which is great since we have a small pomeranian.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2024-03-02-moving-from-london-to-the-bay-area-and-what-changed_16.webp\"></p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"conclusion\">Conclusion<a href=\"https://didierlopes.com/blog/moving-from-london-to-the-bay-area-and-what-changed#conclusion\" class=\"hash-link\" aria-label=\"Direct link to Conclusion\" title=\"Direct link to Conclusion\">​</a></h2>\n<p>Overall, I'm very happy that I moved to the US. I think it was the right decision for both the company and my family. Plus the network that I'm building between other founders, customers and investors is something that I couldn't have done in Europe.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/moving-from-london-to-the-bay-area-and-what-changed",
            "title": "Moving from London to the Bay Area and what changed",
            "summary": "Moving from London to the Bay Area and what changed",
            "date_modified": "2024-03-02T00:00:00.000Z",
            "tags": [
                "learning",
                "experience",
                "growth",
                "moving",
                "london",
                "bay",
                "us",
                "travel"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/openbb-copilot-now-available-to-all-terminal-pro-users",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2024-02-27-openbb-copilot-now-available-to-all-terminal-pro-users.webp\"></p>\n<p>For the past few weeks, we’ve been working on the OpenBB Copilot, an ever-present financial analyst at your fingertips with the OpenBB Terminal Pro.</p>\n<br>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>The <a href=\"https://openbb.co/use-cases/ai\" target=\"_blank\" rel=\"noopener noreferrer\">OpenBB Copilo</a> is our latest addition to the <a href=\"https://openbb.co/products/pro\" target=\"_blank\" rel=\"noopener noreferrer\">Terminal Pro</a>, and we could not be more excited to share it with you.</p>\n<p>If you don't have access yet, join the <a href=\"https://my.openbb.co/app/pro/early-access\" target=\"_blank\" rel=\"noopener noreferrer\">Terminal Pro waitlist</a> and enjoy your 3-week free trial soon!</p>\n<p>Now, take a moment to meet your new <strong>AI investment research partner</strong>.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"what-can-the-openbb-copilot-do\">What can the OpenBB Copilot do?<a href=\"https://didierlopes.com/blog/openbb-copilot-now-available-to-all-terminal-pro-users#what-can-the-openbb-copilot-do\" class=\"hash-link\" aria-label=\"Direct link to What can the OpenBB Copilot do?\" title=\"Direct link to What can the OpenBB Copilot do?\">​</a></h2>\n<p>OpenBB Copilot is multi-functional and can perform several tasks that are useful to analysts. We’ll be exploring these below.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"generic-financial-knowledge\">Generic financial knowledge<a href=\"https://didierlopes.com/blog/openbb-copilot-now-available-to-all-terminal-pro-users#generic-financial-knowledge\" class=\"hash-link\" aria-label=\"Direct link to Generic financial knowledge\" title=\"Direct link to Generic financial knowledge\">​</a></h3>\n<p>Using OpenBB Copilot, you can ask any general financial question. For example:</p>\n<p><strong>What is the P/E ratio?</strong></p>\n<video controls=\"\"><source src=\"https://openbb-cms.directus.app/assets/7c8c9658-4c4d-4090-8a61-826de823981b\"></video>\n<p>As an additional bonus feature, OpenBB Copilot includes a LaTeX renderer to display mathematical formulas and equations.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"conversation-capability\">Conversation capability<a href=\"https://didierlopes.com/blog/openbb-copilot-now-available-to-all-terminal-pro-users#conversation-capability\" class=\"hash-link\" aria-label=\"Direct link to Conversation capability\" title=\"Direct link to Conversation capability\">​</a></h3>\n<p>OpenBB Copilot is a conversational agent and is, therefore, aware of the chat history of the current conversation.</p>\n<p>As a result, you can ask follow-up questions and steer OpenBB Copilot toward your line of inquiry while developing an investment thesis.</p>\n<p>To clear the message history, for example, when investigating a new asset, you can click on the trashcan icon to start a new conversation.</p>\n<video controls=\"\"><source src=\"https://openbb-cms.directus.app/assets/3e1170f2-59b4-458a-bc6e-cd86c688b8db\"></video>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"terminal-pro-as-context\">Terminal Pro as context<a href=\"https://didierlopes.com/blog/openbb-copilot-now-available-to-all-terminal-pro-users#terminal-pro-as-context\" class=\"hash-link\" aria-label=\"Direct link to Terminal Pro as context\" title=\"Direct link to Terminal Pro as context\">​</a></h3>\n<p>If you ask questions about the data on the dashboard, OpenBB Copilot will query the Terminal Pro for the data necessary to answer your query.</p>\n<p>The Copilot has access to the dashboard metadata on the backend and can decide to retrieve data from any of the widgets currently on your dashboard.</p>\n<p>In most cases, if you can see the data on your dashboard, you can assume OpenBB Copilot has access to it.</p>\n<video controls=\"\"><source src=\"https://openbb-cms.directus.app/assets/6c22201f-67ce-49a7-ab4d-213b594c657b\"></video>\n<p>This is an application of what’s known in the AI world as function calling, which allows LLMs to interact with external systems.</p>\n<p>The OpenBB Copilot can choose to automatically retrieve the data from your dashboard if it needs it to answer your query.</p>\n<p>The advantage of this approach is that, since you can retrieve data from any widget, you can also expand OpenBB Copilot’s knowledge by adding custom widgets or by bringing your own data to the Terminal Pro.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"query-specific-widgets\">Query specific widgets<a href=\"https://didierlopes.com/blog/openbb-copilot-now-available-to-all-terminal-pro-users#query-specific-widgets\" class=\"hash-link\" aria-label=\"Direct link to Query specific widgets\" title=\"Direct link to Query specific widgets\">​</a></h3>\n<p>Sometimes, you may wish to focus your analysis and use OpenBB Copilot with only a specific subset of widgets.</p>\n<p>For example, you may want to use OpenBB Copilot to assist you in a deep analysis of an earnings transcript in the \"Earnings Transcript\" widget without retrieving data from the rest of the dashboard.</p>\n<p>To achieve this, you can chat with specifically selected widgets by clicking on the \"Add widgets as context\".</p>\n<video controls=\"\"><source src=\"https://openbb-cms.directus.app/assets/dc74b30a-73ed-4b85-af23-9bb8ab9c844c\"></video>\n<p>Selecting a widget will make that widget's data available to OpenBB Copilot while excluding all the other widgets.</p>\n<p>You can then use the Copilot as normal and the unselected widgets will be ignored by the Copilot.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"query-your-own-documents\">Query your own documents<a href=\"https://didierlopes.com/blog/openbb-copilot-now-available-to-all-terminal-pro-users#query-your-own-documents\" class=\"hash-link\" aria-label=\"Direct link to Query your own documents\" title=\"Direct link to Query your own documents\">​</a></h3>\n<p>You’re also not limited by the data that is available in Terminal Pro.</p>\n<p>You can upload your own documents for OpenBB Copilot to use as context while answering your queries.</p>\n<p>OpenBB Copilot currently supports txt, PDF, CSV and XLSX documents.</p>\n<video controls=\"\"><source src=\"https://openbb-cms.directus.app/assets/dec690c2-ed07-40c1-8b3e-ff0ad7294258\"></video>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"citations\">Citations<a href=\"https://didierlopes.com/blog/openbb-copilot-now-available-to-all-terminal-pro-users#citations\" class=\"hash-link\" aria-label=\"Direct link to Citations\" title=\"Direct link to Citations\">​</a></h3>\n<p>We understand that sometimes getting an answer from an AI chatbot with financial knowledge isn’t satisfactory.</p>\n<p>You often want to do further research or do your own fact-checking of the sources used to answer to your query.</p>\n<p>That is why OpenBB Copilot provides citations as part of its answers.</p>\n<p>When using the Terminal Pro as context or chatting with your uploaded data files, the Copilot will cite which data sources it used to formulate the answers.</p>\n<p>Simply mouse over the citation to see which widget data was used, or which uploaded file was referenced. For PDF document specifically, the Copilot will also source the specific page that was used to answer your query.</p>\n<video controls=\"\"><source src=\"https://openbb-cms.directus.app/assets/e35a0b2c-8150-4d2b-9743-a72862ba3b6d\"></video>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"what-if-you-dont-want-to-use-our-copilot\">What if you don't want to use our copilot?<a href=\"https://didierlopes.com/blog/openbb-copilot-now-available-to-all-terminal-pro-users#what-if-you-dont-want-to-use-our-copilot\" class=\"hash-link\" aria-label=\"Direct link to What if you don't want to use our copilot?\" title=\"Direct link to What if you don't want to use our copilot?\">​</a></h2>\n<p>You don’t have to. That is the reason we came up with the Bring Your Own Copilot concept.</p>\n<p>If you’re an OpenBB Terminal Pro user, you’re able to bring your own financial Copilot that has been fine-tuned and tweaked on your enterprise’s private data.</p>\n<p>This provides an edge to financial firms as they can access their own fine-tuned LLM with access to real-time data provided by the OpenBB Terminal Pro - making this the perfect combo to perform investment research.</p>\n<p>We have an <a href=\"https://github.com/OpenBB-finance/copilot-for-terminal-pro/tree/main\" target=\"_blank\" rel=\"noopener noreferrer\">open-source repository</a> to help you make your own copilots accessible on the Terminal Pro.</p>\n<p>You can also see the video below:</p>\n<video controls=\"\"><source src=\"https://openbb-cms.directus.app/assets/2703e8d8-2497-40ab-b513-678d78989f5b\"></video>\n<br>\n<p>Check out our <a href=\"https://openbb.co/use-cases/ai\" target=\"_blank\" rel=\"noopener noreferrer\">AI page</a> to learn more about these features and stay updated in the future.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/openbb-copilot-now-available-to-all-terminal-pro-users",
            "title": "OpenBB Copilot is now available to all Terminal Pro users",
            "summary": "Introducing the OpenBB Copilot, an ever-present financial analyst at your fingertips with the OpenBB Terminal Pro.",
            "date_modified": "2024-02-27T00:00:00.000Z",
            "tags": [
                "openbb",
                "copilot",
                "generative-ai",
                "ai",
                "llm"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/12-things-i-learned-in-2023",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2024-01-22-12-things-i-learned-in-2023.webp\"></p>\n<br>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>The 12 things I learned in 2023</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"1-dont-delegate-anything-that-you-wouldnt-do-yourself\">1. Don't delegate anything that you wouldn't do yourself.<a href=\"https://didierlopes.com/blog/12-things-i-learned-in-2023#1-dont-delegate-anything-that-you-wouldnt-do-yourself\" class=\"hash-link\" aria-label=\"Direct link to 1. Don't delegate anything that you wouldn't do yourself.\" title=\"Direct link to 1. Don't delegate anything that you wouldn't do yourself.\">​</a></h3>\n<p>It's extremely important to work on little things to show your team that nothing is too small to spend time on, and sets a precedent that you are willing to work on the ground next to them.</p>\n<p>E.g. Elon Musk sleeping at the gigafactory to show his team that he was there next to them.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"2-be-curious-and-humble-enough-to-be-willing-to-ask-dumb-questions\">2. Be curious and humble enough to be willing to ask dumb questions.<a href=\"https://didierlopes.com/blog/12-things-i-learned-in-2023#2-be-curious-and-humble-enough-to-be-willing-to-ask-dumb-questions\" class=\"hash-link\" aria-label=\"Direct link to 2. Be curious and humble enough to be willing to ask dumb questions.\" title=\"Direct link to 2. Be curious and humble enough to be willing to ask dumb questions.\">​</a></h3>\n<p>If I don't know something, I never pretend understanding what the person is talking about.</p>\n<p>I would take the knowledge over a \"smart\" label, any day.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"3-implement-feedback-loops-on-everything-you-do-otherwise-you-cant-adapt\">3. Implement feedback loops on everything you do, otherwise you can't adapt.<a href=\"https://didierlopes.com/blog/12-things-i-learned-in-2023#3-implement-feedback-loops-on-everything-you-do-otherwise-you-cant-adapt\" class=\"hash-link\" aria-label=\"Direct link to 3. Implement feedback loops on everything you do, otherwise you can't adapt.\" title=\"Direct link to 3. Implement feedback loops on everything you do, otherwise you can't adapt.\">​</a></h3>\n<p>Last year I decided to work on <a href=\"https://openbb.co/company/open/team\" target=\"_blank\" rel=\"noopener noreferrer\">tracking our employee engagement</a>, and this is one of the best and most valuable initiatives I have worked on.</p>\n<p>It has provided us tons of feedback that we were able to act on, and improve what it's like to work for OpenBB. More information on this <a href=\"https://openbb.co/blog/employee-engagement\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"4-ux-is-more-important-than-ui\">4. UX is more important than UI.<a href=\"https://didierlopes.com/blog/12-things-i-learned-in-2023#4-ux-is-more-important-than-ui\" class=\"hash-link\" aria-label=\"Direct link to 4. UX is more important than UI.\" title=\"Direct link to 4. UX is more important than UI.\">​</a></h3>\n<p>I keep seeing tweets about UI improvements on a website and/or product. I love that type of posts, and wish there was a similar trend going on for UX improvements.</p>\n<p>While UI is critical to attract users, UX is king to retain them.</p>\n<p>It's like dating - the looks is in the UI and the personality is the UX.</p>\n<p>While they may be perceived as their own separate bubble, they are not. Someone with an amazing personality (UX) will appear as more beautiful (UI).</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"5-if-in-presence-of-a-2-way-door-decision-you-should-decide-fast\">5. If in presence of a 2-way door decision, you should decide fast.<a href=\"https://didierlopes.com/blog/12-things-i-learned-in-2023#5-if-in-presence-of-a-2-way-door-decision-you-should-decide-fast\" class=\"hash-link\" aria-label=\"Direct link to 5. If in presence of a 2-way door decision, you should decide fast.\" title=\"Direct link to 5. If in presence of a 2-way door decision, you should decide fast.\">​</a></h3>\n<p>Being fast to decide to do A instead of B in a 2-way door decision is ideal because even if that wasn't the correct decision, adapting after will still be better than being stuck at the decision stage.</p>\n<p>Plus, you'll be surprised by how many time you actually get it right given the level of context and knowledge you have in the space.</p>\n<p>Knowing what is a 1 and a 2-way door decision, separates great from poor leaders.</p>\n<p>I like <a href=\"https://tiktok.com/@evancarmichael/video/7317081673865235717\" target=\"_blank\" rel=\"noopener noreferrer\">this video</a> from Jeff Bezzos talking about this.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"6-theres-a-ton-of-data-in-intuition-and-common-sense\">6. There's a ton of data in intuition and common sense.<a href=\"https://didierlopes.com/blog/12-things-i-learned-in-2023#6-theres-a-ton-of-data-in-intuition-and-common-sense\" class=\"hash-link\" aria-label=\"Direct link to 6. There's a ton of data in intuition and common sense.\" title=\"Direct link to 6. There's a ton of data in intuition and common sense.\">​</a></h3>\n<p>As a leader, most of the times you have to make decisions with no hard data evidence. And by hard data I mean a spreadsheet with numbers or a powerpoint with charts.</p>\n<p>However, you do have that data. It's just not in a clean format and lives on your head.</p>\n<p>This data has been aggregating by spending more time thinking about the problem you are solving than anyone else, by talking with customers, by talking with partners, and everything in between.</p>\n<p>Trust your intuition, more often than not presentations are done to justify decisions that you knew were right all along. Skip that and you will be able to move faster.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"7-hear-feedback-from-everyone-but-only-listen-from-a-few\">7. Hear feedback from everyone but only listen from a few.<a href=\"https://didierlopes.com/blog/12-things-i-learned-in-2023#7-hear-feedback-from-everyone-but-only-listen-from-a-few\" class=\"hash-link\" aria-label=\"Direct link to 7. Hear feedback from everyone but only listen from a few.\" title=\"Direct link to 7. Hear feedback from everyone but only listen from a few.\">​</a></h3>\n<p>People paying for your product, will provide you 10x feedback compared to others. Use common sense for others.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"8-be-there-for-your-team\">8. Be there for your team.<a href=\"https://didierlopes.com/blog/12-things-i-learned-in-2023#8-be-there-for-your-team\" class=\"hash-link\" aria-label=\"Direct link to 8. Be there for your team.\" title=\"Direct link to 8. Be there for your team.\">​</a></h3>\n<p>Make sure to remind your team that you couldn't do it without them.</p>\n<p>A single off-line event per year is not enough.</p>\n<p>Show that you care by being there: asking about their family/pets/hobbies, messaging them when they perform above expectations, send them gifts when something negative happens, ... act like a friend but manage like a captain</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"9-fire-b-and-c-players-early\">9. Fire B and C players early.<a href=\"https://didierlopes.com/blog/12-things-i-learned-in-2023#9-fire-b-and-c-players-early\" class=\"hash-link\" aria-label=\"Direct link to 9. Fire B and C players early.\" title=\"Direct link to 9. Fire B and C players early.\">​</a></h3>\n<p>Keeping a team of A players is hard but extremely rewarding, and necessary.</p>\n<p>It sets the precedent that average work is not enough to work at your company, and high performers will want to work for you to be surrounded by people that push them everyday.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"10-distribution-is-more-important-than-product\">10. Distribution is more important than product.<a href=\"https://didierlopes.com/blog/12-things-i-learned-in-2023#10-distribution-is-more-important-than-product\" class=\"hash-link\" aria-label=\"Direct link to 10. Distribution is more important than product.\" title=\"Direct link to 10. Distribution is more important than product.\">​</a></h3>\n<p>Took me some time to understand this, but I have no doubts about this now.</p>\n<p>This is why the sentence of \"A good product with great distribution will almost always beat a great product with poor distribution.\"</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"11-leave-your-comfort-zone\">11. Leave your comfort zone.<a href=\"https://didierlopes.com/blog/12-things-i-learned-in-2023#11-leave-your-comfort-zone\" class=\"hash-link\" aria-label=\"Direct link to 11. Leave your comfort zone.\" title=\"Direct link to 11. Leave your comfort zone.\">​</a></h3>\n<p>I'm really shy on stage and this year I've presented a few times. And I've impressed myself, while I'm far from good I've come a long way.</p>\n<p>When i started learning english my goal was to be able to make people laugh in english, that took a while.</p>\n<p>I've now been able to make people laugh whilst on stage and I didn't expect that I'd be able to do this anytime soon.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"12-tell-your-loved-ones-how-much-they-mean-to-you\">12. Tell your loved ones how much they mean to you.<a href=\"https://didierlopes.com/blog/12-things-i-learned-in-2023#12-tell-your-loved-ones-how-much-they-mean-to-you\" class=\"hash-link\" aria-label=\"Direct link to 12. Tell your loved ones how much they mean to you.\" title=\"Direct link to 12. Tell your loved ones how much they mean to you.\">​</a></h3>\n<p>Most of us have someone by our side that allow us to keep performing at highest level day in and day out.</p>\n<p>Ensure they know you couldn't be the person you are today without them.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/12-things-i-learned-in-2023",
            "title": "12 things I learned in 2023",
            "summary": "The 12 things I learned in 2023",
            "date_modified": "2024-01-22T00:00:00.000Z",
            "tags": [
                "learnings",
                "reflection",
                "leadership",
                "startup",
                "growth",
                "product-management",
                "user-experience",
                "decision-making",
                "life-lessons"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/introducing-the-openbb-add-in-for-excel",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2024-01-17-introducing-the-openbb-add-in-for-excel.webp\"></p>\n<br>\n<p>We acknowledged the enduring centrality of Excel in the financial sector, so we're now making data from the Terminal Pro readily available in Excel. We're also excitedly working to integrate the \"Bring Your Own Data\" feature into our Excel Add-in, a move we foresee as a transformative step in the financial data industry.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"introduction\">Introduction<a href=\"https://didierlopes.com/blog/introducing-the-openbb-add-in-for-excel#introduction\" class=\"hash-link\" aria-label=\"Direct link to Introduction\" title=\"Direct link to Introduction\">​</a></h2>\n<p>Building something people truly want requires direct engagement with them. After conducting over 100 interviews with analysts and quants, three key insights surfaced:</p>\n<ol>\n<li>\n<p>The financial world runs on Excel.</p>\n</li>\n<li>\n<p>The primary value of the OpenBB Terminal Pro lies in its customization (bring your own data + widget/dashboard creation) and AI features.</p>\n</li>\n<li>\n<p>The financial world, <strong>LITERALLY</strong>, still runs on Excel.</p>\n</li>\n</ol>\n<p>For topic number 2, we were well underway towards building the <a href=\"https://openbb.co/products/pro\" target=\"_blank\" rel=\"noopener noreferrer\">Terminal Pro</a> as the most customizable and efficient financial terminal.</p>\n<p>But for topics number 1 and 3, we weren’t.</p>\n<p>So we devised a small task force to tackle this effort and work with design partners towards building the <a href=\"https://openbb.co/products/excel\" target=\"_blank\" rel=\"noopener noreferrer\">OpenBB Add-in for Excel</a>.</p>\n<p>The goal was simple: <strong>financial data available on the Terminal Pro should be accessible in Excel</strong>.</p>\n<p>But as we do for all our products, we wanted to understand where this product would sit in our ecosystem.</p>\n<p>Since the Terminal Pro offers a basic data tier (including historical price, fundamentals, analyst estimates, news, macro-economy, and forex) with redistribution rights, we decided to make those same datasets available in Excel.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2024-01-17-introducing-the-openbb-add-in-for-excel_1.webp\"></p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"getting-started\">Getting Started<a href=\"https://didierlopes.com/blog/introducing-the-openbb-add-in-for-excel#getting-started\" class=\"hash-link\" aria-label=\"Direct link to Getting Started\" title=\"Direct link to Getting Started\">​</a></h2>\n<p>So, in simple terms, we allow the user to access financial data right from Excel, by connecting with the OpenBB server to do the data request.</p>\n<p>In the example below you can see that we are using the formula <code>=OBB.EQUITY.ESTIMATES.PRICE_TARGET(\"AAPL\")</code> which retrieves the latest data about AAPL’s price target.</p>\n<p>You can read more information about it in our <a href=\"https://docs.openbb.co/excel/reference/equity/estimates/price_target\" target=\"_blank\" rel=\"noopener noreferrer\">Documentation</a>.</p>\n<p>This is how it looks:</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2024-01-17-introducing-the-openbb-add-in-for-excel_2.webp\"></p>\n<p>This was a huge step for us.</p>\n<p>However, another question came up:</p>\n<p><strong>As the datasets keep expanding, discoverability will become a big problem.</strong></p>\n<p>And we haven’t been around for 40 years for users to be familiar with our terminology.</p>\n<p>So, how would users know what function to use, to access the datasets they are interested in?</p>\n<p>We figured that enterprise users would be interested in accessing the data they are already visualizing in the <a href=\"https://openbb.co/products/pro\" target=\"_blank\" rel=\"noopener noreferrer\">OpenBB Terminal Pro</a>.</p>\n<p>So we allowed them to get the Excel function directly from each widget:</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2024-01-17-introducing-the-openbb-add-in-for-excel_3.webp\"></p>\n<p>After clicking on the “Functions” button in the ellipsis icon of the widget data you are interested in, this is what a user sees:</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2024-01-17-introducing-the-openbb-add-in-for-excel_4.webp\"></p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"templates\">Templates<a href=\"https://didierlopes.com/blog/introducing-the-openbb-add-in-for-excel#templates\" class=\"hash-link\" aria-label=\"Direct link to Templates\" title=\"Direct link to Templates\">​</a></h2>\n<p>Since <a href=\"https://my.openbb.co/app/pro\" target=\"_blank\" rel=\"noopener noreferrer\">OpenBB Terminal Pro</a> users are used to the templates they have access to with our product, e.g. our equity analyst template:</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2024-01-17-introducing-the-openbb-add-in-for-excel_5.webp\"></p>\n<p>We ensured that similar templates were available for the Excel Add-in, and you can find them <a href=\"https://my.openbb.co/app/excel/templates\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2024-01-17-introducing-the-openbb-add-in-for-excel_6.webp\"></p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"whats-next\">What's Next<a href=\"https://didierlopes.com/blog/introducing-the-openbb-add-in-for-excel#whats-next\" class=\"hash-link\" aria-label=\"Direct link to What's Next\" title=\"Direct link to What's Next\">​</a></h2>\n<p>Last but not least, we are working on the upcoming integration of the \"Bring Your Own Data\" (BYOD) feature into our Excel Add-in.</p>\n<p>Until now, this capability has been exclusive to the OpenBB Terminal Pro and is a <strong>cornerstone of our offering</strong>.</p>\n<p>But it doesn’t have to stop there.</p>\n<p>Our foundation on an open-source platform empowers us to facilitate open data access across multiple interfaces, whether through the Terminal Pro or the Excel Add-in.</p>\n<p>We expect this to be a complete game-changer in the industry. While numerous financial Excel add-ins exist, they lack the flexibility to seamlessly incorporate third-party or proprietary datasets.</p>\n<p>We are currently working with design partners on this. So if this sounds like something you are interested in - please reach out.</p>\n<p>We have a 5,000+ <a href=\"https://my.openbb.co/app/pro/early-access\" target=\"_blank\" rel=\"noopener noreferrer\">waitlist</a> to the Terminal Pro and have already started onboarding users. As part of the Terminal Pro free trial, you will be granted access to the OpenBB Add-in for Excel as long as you have Microsoft Excel.</p>\n<p>Wondering how to get started easily? Here is a video to help:</p>\n<div class=\"flex place-items-center justify-center items-center rounded-sm mx-auto\"><iframe src=\"https://www.youtube.com/embed/Rn3M36H_6Cw?si=hxCf3zMw2y4kIi7N\" width=\"800\" height=\"400\"></iframe></div>\n<br>\n<p>You can find more tutorials in the <a href=\"https://docs.openbb.co/excel/getting-started/installation\" target=\"_blank\" rel=\"noopener noreferrer\">Documentation</a>.</p>\n<p>For more information, contact us at <a href=\"mailto:sales@openbb.finance\" target=\"_blank\" rel=\"noopener noreferrer\">sales@openbb.finance</a> or sign up for <a href=\"https://my.openbb.co/app/pro/early-access\" target=\"_blank\" rel=\"noopener noreferrer\">our waitlist</a>.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/introducing-the-openbb-add-in-for-excel",
            "title": "Introducing the OpenBB Add-in for Excel",
            "summary": "We acknowledged the enduring centrality of Excel in the financial sector, so we're now making data from the Terminal Pro readily available in Excel. We're also excitedly working to integrate the \"Bring Your Own Data\" feature into our Excel Add-in, a move we foresee as a transformative step in the financial data industry.",
            "date_modified": "2024-01-17T00:00:00.000Z",
            "tags": [
                "excel",
                "launch",
                "openbb",
                "announcement"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/slack-gpt-summarizing-messages",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2024-01-15-slack-gpt-summarizing-messages.webp\"></p>\n<br>\n<p>The SlackGPT is a Slack bot that summarizes conversations and sends you a summary per channel.</p>\n<p>The open source code is available <a href=\"https://github.com/DidierRLopes/slackGPT\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"context\">Context<a href=\"https://didierlopes.com/blog/slack-gpt-summarizing-messages#context\" class=\"hash-link\" aria-label=\"Direct link to Context\" title=\"Direct link to Context\">​</a></h2>\n<p>Saw someone the other day tweeting that it would be great if there was a SlackGPT that could summarize all the Slack messages for when they wake up.</p>\n<p>And I immediately related to that. We are a team of 20, and I'm the only one in SF. So when I wake up, most of the team is already half a day in or has just wrapped up.</p>\n<p>That means that I always spend the first 30 minutes of the day reading messages to catch-up on everything.</p>\n<p>And tonight felt like hacking something quick.</p>\n<p>So I created a script that:</p>\n<ul>\n<li>Reads all Slack messages from the time I go to bed</li>\n<li>Summarizes the conversation of each channel</li>\n<li>The bot sends me a message with this summary</li>\n</ul>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"getting-started\">Getting Started<a href=\"https://didierlopes.com/blog/slack-gpt-summarizing-messages#getting-started\" class=\"hash-link\" aria-label=\"Direct link to Getting Started\" title=\"Direct link to Getting Started\">​</a></h2>\n<p>Clone the open source project <a href=\"https://github.com/DidierRLopes/slackGPT\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"slack-api\">Slack API<a href=\"https://didierlopes.com/blog/slack-gpt-summarizing-messages#slack-api\" class=\"hash-link\" aria-label=\"Direct link to Slack API\" title=\"Direct link to Slack API\">​</a></h3>\n<ol>\n<li>\n<p>Go to <a href=\"https://api.slack.com/apps\" target=\"_blank\" rel=\"noopener noreferrer\">Slack API page</a> and create a new app.</p>\n</li>\n<li>\n<p>Install the app in the workspace you are interested in summarizing Slack messages.</p>\n</li>\n<li>\n<p>Get the User OAuth Token which exists in the Install App settings. This will be needed to use Slack's SDK. Set this value as the <code>SLACK_TOKEN</code> on a <code>.env</code> file if you want to run the script locally or as a GitHub secret if you want to leverage the GitHub workflow.</p>\n</li>\n</ol>\n<br>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2024-01-15-slack-gpt-summarizing-messages_1.webp\"></p>\n<ol start=\"4\">\n<li>\n<p>Create a <strong>Webhook URL</strong> for your channel so that you can receive messages' summary. Set this value as the <code>SLACK_WEBHOOK_URL`` on a </code>.env` file if you want to run the script locally or as a GitHub secret if you want to leverage the GitHub workflow.</p>\n</li>\n<li>\n<p>Depending on the type of access needed, different <strong>User Token Scopes</strong> need to be set. Here's the methods that we will need and the associated user token scopes.</p>\n<ul>\n<li>\n<p>conversations_history: This method retrieves a conversation's history of messages and events. It requires the <strong>channels<!-- -->:history</strong> scope for public channels, or <strong>groups<!-- -->:history</strong> for private channels and im<!-- -->:history<!-- --> for direct messages.</p>\n</li>\n<li>\n<p>users_info: This method returns information about a user. It requires the <strong>users<!-- -->:read</strong> scope.</p>\n</li>\n<li>\n<p>conversations_info: This method retrieves information about a conversation. It requires the <strong>channels<!-- -->:read</strong> scope for public channels, or <strong>groups<!-- -->:read</strong> for private channels and im<!-- -->:read<!-- --> for direct messages.</p>\n</li>\n</ul>\n</li>\n</ol>\n<br>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2024-01-15-slack-gpt-summarizing-messages_2.webp\"></p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"openai-api\">OpenAI API<a href=\"https://didierlopes.com/blog/slack-gpt-summarizing-messages#openai-api\" class=\"hash-link\" aria-label=\"Direct link to OpenAI API\" title=\"Direct link to OpenAI API\">​</a></h3>\n<p>Go to <a href=\"https://platform.openai.com/api-keys\" target=\"_blank\" rel=\"noopener noreferrer\">OpenAI API page</a> to extract the API key. Set this value as the <code>OPENAI_API_KEY</code> on a <code>.env</code> file if you want to run the script locally or as a GitHub secret if you want to leverage the GitHub workflow.</p>\n<br>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2024-01-15-slack-gpt-summarizing-messages_3.webp\"></p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"slack-channels\">Slack channels<a href=\"https://didierlopes.com/blog/slack-gpt-summarizing-messages#slack-channels\" class=\"hash-link\" aria-label=\"Direct link to Slack channels\" title=\"Direct link to Slack channels\">​</a></h3>\n<p>Get the Channel IDs that you are interested in reading messages from.</p>\n<p>Set those values as the <code>SLACK_CHANNEL_IDS</code> on a <code>.env</code> file if you want to run the script locally or as a GitHub secret if you want to leverage the GitHub workflow. If you want to read from multiple channels you can set <code>SLACK_CHANNEL_IDS</code> with multiple IDs separated by commas (with no space), e.g. ABC123,DEF456,GHI789.</p>\n<br>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2024-01-15-slack-gpt-summarizing-messages_4.webp\"></p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"running\">Running<a href=\"https://didierlopes.com/blog/slack-gpt-summarizing-messages#running\" class=\"hash-link\" aria-label=\"Direct link to Running\" title=\"Direct link to Running\">​</a></h3>\n<p>After you fork the project <a href=\"https://github.com/DidierRLopes/slackGPT\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>, there are 2 ways you can run the code.</p>\n<ol>\n<li>\n<p>Ad-hoc by running the python script with <code>python slackgpt.py</code></p>\n</li>\n<li>\n<p>Automatically, by leveraging GitHub actions. For this you will need to set up GitHub secrets and you can modify <a href=\"https://github.com/DidierRLopes/slackGPT/blob/main/.github/workflows/main.yml\" target=\"_blank\" rel=\"noopener noreferrer\">this workflow</a> in order to change the frequency of the messages sumary.</p>\n</li>\n</ol>\n<p>The most important part of this script is the <code>cron: '0 8 * * 1-5'</code> which specifies the frequency. In this case, the expression means that the task will run at 8:00 AM from Monday to Friday, and breaks down as follows:</p>\n<ul>\n<li>\n<p>0: Specifies the minute when the task will run (in this case, 0 minutes).</p>\n</li>\n<li>\n<p>8: Specifies the hour when the task will run (in this case, 8 AM).</p>\n</li>\n<li>\n<p>*: Represents any day of the month, meaning the task is not restricted to a specific day.</p>\n</li>\n<li>\n<p>*: Represents any month, meaning the task is not restricted to a specific month.</p>\n</li>\n<li>\n<p>1-5: Specifies the days of the week when the task will run (Monday to Friday).</p>\n</li>\n</ul>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"results\">Results<a href=\"https://didierlopes.com/blog/slack-gpt-summarizing-messages#results\" class=\"hash-link\" aria-label=\"Direct link to Results\" title=\"Direct link to Results\">​</a></h2>\n<p>By inputting the following text on the Slack channel of my choice:</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2024-01-15-slack-gpt-summarizing-messages_5.webp\"></p>\n<p>The SlackGPT summarized it as follows:</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2024-01-15-slack-gpt-summarizing-messages_6.webp\"></p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/slack-gpt-summarizing-messages",
            "title": "SlackGPT - Your Slack bot that summarizes unread messages",
            "summary": "The SlackGPT is a Slack bot that summarizes conversations and sends you a summary per channel.",
            "date_modified": "2024-01-15T00:00:00.000Z",
            "tags": [
                "slack",
                "slackgpt",
                "llm",
                "summarization",
                "open-source",
                "bot"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/building-my-personal-website-in-docusaurus",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2024-01-08-building-my-personal-website-in-docusaurus.webp\"></p>\n<br>\n<p>How I'm using Docusaurus to build my own personal website.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>One of my goals for 2023 was to learn web development. Given that I knew 0 to nothing last year, I am extremely happy with my progress.</p>\n<p>I never had the time to fully dedicate to it in terms of doing a program/course — but as with anything in life, the best way to learn is by doing.</p>\n<p>And this year I worked on web development for:</p>\n<ul>\n<li>OpenBB Hub — <a href=\"https://my.openbb.co/\" target=\"_blank\" rel=\"noopener noreferrer\">https://my.openbb.co</a></li>\n<li>OpenBB marketing website — <a href=\"https://openbb.co/\" target=\"_blank\" rel=\"noopener noreferrer\">https://openbb.co</a></li>\n<li>OpenBB docs — <a href=\"https://docs.openbb.co/\" target=\"_blank\" rel=\"noopener noreferrer\">https://docs.openbb.co</a></li>\n<li>OpenBB Terminal Pro — <a href=\"https://pro.openbb.co/\" target=\"_blank\" rel=\"noopener noreferrer\">https://pro.openbb.co</a></li>\n</ul>\n<p>Thank you José Donato for always helping me with anything!</p>\n<p>In addition, I’ve always wanted to have my own personal website. So I felt that this would be the perfect opportunity to do so as I could spend some time with it over weekends.</p>\n<p>And so I did, and open source here: <a href=\"https://github.com/DidierRLopes/personal-website\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/DidierRLopes/personal-website</a></p>\n<p>However, this website was taking too much of my spare time, which I could use for more important work. And at the time I became very familiar with Docusaurus, which is what we use for OpenBB docs.</p>\n<p>So I thought — why not just use Docusaurus to make my personal website? It’s easy to edit, I’m already very familiar with the architecture, and it’s very easy to update when there’s new information.</p>\n<p>So that’s what I did, and also made the entire code open source here: <a href=\"https://github.com/DidierRLopes/my-website\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/DidierRLopes/my-website</a></p>\n<p>You can access the full website here — <a href=\"https://didierlopes.com/\" target=\"_blank\" rel=\"noopener noreferrer\">https://didierlopes.com/</a>, and there you can find: my personal projects, books I’ve read or want to read, interviews/webinars/podcasts, resume or even my blog.</p>\n<p>Any feedback is welcome.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/building-my-personal-website-in-docusaurus",
            "title": "Building my personal website in Docusaurus",
            "summary": "How I'm using Docusaurus to build my own personal website.",
            "date_modified": "2024-01-08T00:00:00.000Z",
            "tags": [
                "docusaurus",
                "website",
                "blog"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/prediction-for-2024",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2024-01-01-prediction-for-2024.webp\"></p>\n<br>\n<p>Companies will own multiple fine-tuned LLMs/SLMs for specific tasks.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>LLMs like ChatGPT are great for showing what these models are capable of doing in terms of breadth, but at the end of the day, you’re going to look for depth. Instead of relying on one-size-fits-all solutions, companies will look towards the integration of multiple, fine-tuned language models tailored for specific actions.</p>\n<p>Enterprises are recognizing the importance of accuracy in their AI applications. General-purpose language models have been revolutionary, but the demand for specialized models is on the rise. From customer support interactions to complex data analysis, having dedicated language models for specific tasks enhances accuracy and efficiency. This is easy to understand since the weights that are being used for the LLM to have a big breadth of knowledge are repurposed for depth.</p>\n<p>Personalization is no longer a luxury but a necessity. Specialized language models enable enterprises to deliver personalized experiences to their customers. We have to assume that everyone is utilizing the same models today, so offering ChatGPT in your product isn’t good enough. You need to add alpha to it. And that is done through fine-tuning utilizing your private data.</p>\n<p>In an era of increasing cyber threats and stringent regulations, the deployment of fine-tuned language models allows enterprises to enhance their security measures and ensure compliance with industry standards.</p>\n<p>As for the financial industry, this is 100% going to happen. Firms will fine-tune language models locally utilizing their proprietary datasets and providing access to their Snowflake/Elastic/ClickHouse/.. instances. This collection of models will effectively enhance the productivity of the firm by 2/3x, even displacing jobs.</p>\n<p>We are preparing for this shift at OpenBB and I spent the last few days working on a proof-of-concept with José Donato that will allow users to bring their own copilots to the Terminal Pro. And even have these interact with each other.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2024-01-01-prediction-for-2024_1.webp\"></p>\n<p>For a video on how this works you can check: <a href=\"https://x.com/josedonato__/status/1741151037031845986?s=20\" target=\"_blank\" rel=\"noopener noreferrer\">https://x.com/josedonato__/status/1741151037031845986?s=20</a></p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/prediction-for-2024",
            "title": "Prediction for 2024",
            "summary": "Companies will own multiple fine-tuned LLMs/SLMs for specific tasks.",
            "date_modified": "2024-01-01T00:00:00.000Z",
            "tags": [
                "openbb",
                "finance",
                "ai",
                "agents",
                "copilot",
                "llm",
                "pro",
                "fine-tune"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/creating-an-ai-powered-financial-analyst",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2023-12-27-creating-an-ai-powered-financial-analyst.webp\"></p>\n<br>\n<p>Our Platform aims to empower the OpenBB Copilot, an AI-powered financial analyst, to perform tasks ranging from knowledge retrieval to fully autonomous analysis. The architecture involves task decomposition, tool retrieval, and subtask agents, showcasing impressive results in both deterministic and non-deterministic workflows. Read on to explore its capabilities and don't forget to watch the demos.</p>\n<p>The open source code is available <a href=\"https://github.com/OpenBB-finance/openbb-agents\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"introduction\">Introduction<a href=\"https://didierlopes.com/blog/creating-an-ai-powered-financial-analyst#introduction\" class=\"hash-link\" aria-label=\"Direct link to Introduction\" title=\"Direct link to Introduction\">​</a></h2>\n<p>At OpenBB, we have been thinking deeply about how AI will impact the lives of analysts and quants. We recently <a href=\"https://openbb.co/blog/goodbye-openbb-sdk-hello-openbb-platform\" target=\"_blank\" rel=\"noopener noreferrer\">announced the OpenBB Platform</a> and have refactored it from the ground up to make it easier and simpler for quants/developers to access financial data. In addition, we hired a new head of AI to lead our AI efforts - you can read more about it <a href=\"https://openbb.co/blog/revolutionizing-ai-at-openbb-with-new-leader-michael-struwig\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<p>I did a 20-minute presentation at the Open Core Summit on this topic that you can watch here:</p>\n<div class=\"flex place-items-center justify-center items-center rounded-sm mx-auto\"><iframe src=\"https://www.youtube.com/embed/A-43EKK2PhE?si=o_lO_lVLpWwwfbvF\" width=\"800\" height=\"400\"></iframe></div>\n<br>\n<p>Otherwise, the following post will summarize what we presented.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"ai-powered-financial-analyst-roadmap\">AI-Powered financial analyst roadmap<a href=\"https://didierlopes.com/blog/creating-an-ai-powered-financial-analyst#ai-powered-financial-analyst-roadmap\" class=\"hash-link\" aria-label=\"Direct link to AI-Powered financial analyst roadmap\" title=\"Direct link to AI-Powered financial analyst roadmap\">​</a></h2>\n<p>When discussing what tasks we wanted our AI-powered Financial Analyst to be able to perform, we arrived at the following levels (in order of complexity):</p>\n<ol>\n<li>\n<p><strong>Knowledge retrieval</strong>: The agent can answer general financial queries without external resources. (eg. ChatGPT \"as-is\"). Here, the agent relies solely on its training data to answer questions.</p>\n</li>\n<li>\n<p><strong>Data retrieval</strong>: The agent can answer queries using information inserted into the context (usually as part of a separate data retrieval process that isn't controlled by the model, such as using <a href=\"https://en.wikipedia.org/wiki/Similarity_search\" target=\"_blank\" rel=\"noopener noreferrer\">similarity search</a> across a knowledge database using the user's query).</p>\n</li>\n<li>\n<p><strong>Autonomous data retrieval</strong>: The agent can answer queries by dynamically retrieving data not currently present in the context or the training data via function calling.</p>\n</li>\n<li>\n<p><strong>Complex workflow execution</strong>: The agent can reason and answer queries that require a logical arrangement of knowledge retrieval, data retrieval, and autonomous data retrieval calling. It includes action planning and decision-making.</p>\n</li>\n<li>\n<p><strong>Fully autonomous analyst</strong>: The agent can do all of the above but is self-directed. The agent can dynamically generate additional hypotheses, modify plans of action, and retrieve the necessary data, all while mid-workflow. The agent can make arguments for certain decisions, carry a discussion on the topic, and reason with you.</p>\n</li>\n</ol>\n<p>Our goal is to enable OpenBB Copilot to perform all of the above. I presented a demo of how it would work in this video:</p>\n<div class=\"flex place-items-center justify-center items-center rounded-sm mx-auto\"><iframe src=\"https://www.youtube.com/embed/V1rYmWWVbIY?si=ShScenxTI4bHtERS\" width=\"800\" height=\"400\"></iframe></div>\n<br>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"two-types-of-prompts\">Two types of prompts<a href=\"https://didierlopes.com/blog/creating-an-ai-powered-financial-analyst#two-types-of-prompts\" class=\"hash-link\" aria-label=\"Direct link to Two types of prompts\" title=\"Direct link to Two types of prompts\">​</a></h2>\n<p>Rather than first building an AI-powered financial analyst for the sake of it, we instead started from what we wanted to achieve. We came up with two distinct prompts and our goal was for the agent to be able to successfully perform both of these, but utilizing the same underlying \"agentic\" architecture.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2023-12-27-creating-an-ai-powered-financial-analyst_1.webp\"></p>\n<ul>\n<li>\n<p><strong>Prompt A (on the left)</strong> - requires linear reasoning (where future answers depend on previous answers). This kind of prompt is generally deterministic, which allows us to access (and verify) the agent's answers immediately because we can check the underlying facts and data. It also involves a few complex operations across multiple steps, such as extracting a list of tickers from an endpoint and iterating through that list using a different endpoint. Then based on those outputs, a reasoning can be made and a final answer is given.</p>\n</li>\n<li>\n<p><strong>Prompt B (on the right)</strong> - requires independent reasoning (fetching and combining different pieces of independent information). This prompt is typically less deterministic and allows us to leverage LLMs to provide alpha by uncovering insights that would be hard for a human to discover (or, at the very least, discover at scale). Instead of telling the agent what to do explicitly, we instead pose a question and expect the agent to execute an analysis and perform reasoning, without specific guidance or guardrails.</p>\n</li>\n</ul>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"openbb-platform\">OpenBB Platform<a href=\"https://didierlopes.com/blog/creating-an-ai-powered-financial-analyst#openbb-platform\" class=\"hash-link\" aria-label=\"Direct link to OpenBB Platform\" title=\"Direct link to OpenBB Platform\">​</a></h2>\n<p>Getting started with our Platform is extremely easy (docs <a href=\"https://docs.openbb.co/platform\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>). All you need is <code>pip install openbb</code> and you are ready to access 100+ different datasets.</p>\n<p>We standardize the data so that you can read our docs once and interact with the Platform the same way, regardless of the type of data you are looking at.</p>\n<p>In addition, using the OpenBB Hub, you can set up your API keys which we can manage on your behalf, and all you need to access data via OpenBB is a Personal Access Token.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2023-12-27-creating-an-ai-powered-financial-analyst_2.webp\"></p>\n<p>Crucially, we use Pydantic for all of our endpoints. This ensures that we have both structured inputs and structured outputs. This is extremely important as we feed these models into our agent so that it understands both the input schema during function calling, but also the output schema of the resulting function call. This is standardized across multiple data vendors across the OpenBB Platform.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2023-12-27-creating-an-ai-powered-financial-analyst_3.webp\"></p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"openbb-tools\">OpenBB Tools<a href=\"https://didierlopes.com/blog/creating-an-ai-powered-financial-analyst#openbb-tools\" class=\"hash-link\" aria-label=\"Direct link to OpenBB Tools\" title=\"Direct link to OpenBB Tools\">​</a></h3>\n<p>From having 100+ different data endpoints that you can access using Python, we created \"tools\" that an agent \"understands\" and can use. This is extremely important since this collection of tools will give real-time data to the agent based on the prompt asked.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2023-12-27-creating-an-ai-powered-financial-analyst_4.webp\"></p>\n<p>Since the OpenBB Platform has high-quality documentation, we use each function's docstring as well as the output field names (with some basic preprocessing). This tweak allows the agent to know where to get the market cap information from, even if it's within a differently-named endpoint (for example the <code>equity.fundamentals.overview</code> endpoint).</p>\n<p>Each of these tool descriptions is converted into embeddings that can be retrieved later on based on the query the user provides. This allows our agent to pick the right tools for the job - i.e. if I want to have access to Apple's market cap, I want to get the tool <code>equity.fundamentals.overview</code> because I know that by providing the symbol <code>AAPL</code> I can get the market cap value.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2023-12-27-creating-an-ai-powered-financial-analyst_5.webp\"></p>\n<p>So, we create a vector store using FAISS (Facebook AI Similarity Search) and OpenAIEmbeddings, although any vector store with similarity search would also work.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"openbb-agent-architecture\">OpenBB Agent Architecture<a href=\"https://didierlopes.com/blog/creating-an-ai-powered-financial-analyst#openbb-agent-architecture\" class=\"hash-link\" aria-label=\"Direct link to OpenBB Agent Architecture\" title=\"Direct link to OpenBB Agent Architecture\">​</a></h2>\n<p align=\"center\"><img width=\"900\" src=\"https://didierlopes.com/blog/2023-12-27-creating-an-ai-powered-financial-analyst_6.webp\"></p>\n<p>This is the overall architecture that our agent will follow, and below we will talk about each of these components individually.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"task-decomposition\">Task Decomposition<a href=\"https://didierlopes.com/blog/creating-an-ai-powered-financial-analyst#task-decomposition\" class=\"hash-link\" aria-label=\"Direct link to Task Decomposition\" title=\"Direct link to Task Decomposition\">​</a></h3>\n<p>First of all, we don't want to tackle the user query in one go. This is because LLMs have limited context. Plus, we want the agent to retrieve all the necessary tools to answer the query. But the vector's store similarity search doesn't work with one prompt that needs multiple different tools. Additionally, similar to human analysts, breaking a larger question up into smaller manageable subquestions leads to better analysis and results.</p>\n<p>So, we break the user's main query into:</p>\n<ul>\n<li>\n<p><strong>List of simpler tasks</strong>: self-explanatory</p>\n</li>\n<li>\n<p><strong>List of tasks dependency</strong>: does the current subtask need a prior subtask to tackle the current subtask?</p>\n</li>\n<li>\n<p><strong>List of \"tool search\" keywords associated with each subtask</strong>: instead of using the subtask question itself to directly retrieve the correct selection of tools using the embeddings in the vector store, empirically we found that if the LLM could select the most important keywords associated with the task using keyword search. This ended up resulting in a big jump in retrieval performance. This is expected since we are effectively reducing the noise. E.g. \"What are Tesla peers\" → \"peers\".</p>\n</li>\n</ul>\n<p>This is the system message we are utilizing:</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2023-12-27-creating-an-ai-powered-financial-analyst_7.webp\"></p>\n<p>To ensure that we have a structured output with the format specified, we create a Pydantic Data model to be used as format in the instruction:</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2023-12-27-creating-an-ai-powered-financial-analyst_8.webp\"></p>\n<p>This is what the code looks like, and you can see that the <code>PydanticOutputParser</code> goes into the <code>format_instructions</code>:</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2023-12-27-creating-an-ai-powered-financial-analyst_9.webp\"></p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"tool-retrieval\">Tool Retrieval<a href=\"https://didierlopes.com/blog/creating-an-ai-powered-financial-analyst#tool-retrieval\" class=\"hash-link\" aria-label=\"Direct link to Tool Retrieval\" title=\"Direct link to Tool Retrieval\">​</a></h3>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2023-12-27-creating-an-ai-powered-financial-analyst_10.webp\"></p>\n<p>This is the function that the agent uses to retrieve the right subset of tools to answer each of the subtasks. Empirically, we found good results by using the similarity score threshold of 0.65. In other words, we retrieve all tools with descriptions that return a better similarity score than that value. In the case where the search yields less than two tools, we return the 2 tools with the highest similarity score instead.</p>\n<p>As previously mentioned, you can see that we are not using the subtask query itself but the keywords associated with it. The embeddings of the keywords are (from experimentation) closer to the embeddings of the correct docstring by focusing solely on a few keywords rather than the entire sentence.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2023-12-27-creating-an-ai-powered-financial-analyst_11.webp\"></p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"subtask-agents\">Subtask Agents<a href=\"https://didierlopes.com/blog/creating-an-ai-powered-financial-analyst#subtask-agents\" class=\"hash-link\" aria-label=\"Direct link to Subtask Agents\" title=\"Direct link to Subtask Agents\">​</a></h3>\n<p>Each subtask agent is provided with the original query from the user, one of the subtasks from the task decomposition step, the output from another subtask agent IF there was a subtask dependency AND a set of retrieved tools necessary to answer the subtask.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2023-12-27-creating-an-ai-powered-financial-analyst_12.webp\"></p>\n<p>This is what the agent looks like:</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2023-12-27-creating-an-ai-powered-financial-analyst_13.webp\"></p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"final-agent\">Final Agent<a href=\"https://didierlopes.com/blog/creating-an-ai-powered-financial-analyst#final-agent\" class=\"hash-link\" aria-label=\"Direct link to Final Agent\" title=\"Direct link to Final Agent\">​</a></h3>\n<p>We then combine the entire context from subquestions and outputs to be given to the final agent:</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2023-12-27-creating-an-ai-powered-financial-analyst_14.webp\"></p>\n<p>Finally, we give the final agent the main prompt and the list of tasks from task decomposition and that's it!</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2023-12-27-creating-an-ai-powered-financial-analyst_15.webp\"></p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"openbb-results\">OpenBB Results<a href=\"https://didierlopes.com/blog/creating-an-ai-powered-financial-analyst#openbb-results\" class=\"hash-link\" aria-label=\"Direct link to OpenBB Results\" title=\"Direct link to OpenBB Results\">​</a></h2>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"prompt-a\">Prompt A<a href=\"https://didierlopes.com/blog/creating-an-ai-powered-financial-analyst#prompt-a\" class=\"hash-link\" aria-label=\"Direct link to Prompt A\" title=\"Direct link to Prompt A\">​</a></h3>\n<p><em>\"Check what are TSLA peers. From those, check which one has the highest market cap. Then, on the ticker that has the highest market cap get the most recent price target estimate from an analyst, and tell me who it was and on what date the estimate was made.\"</em></p>\n<p>The output can be seen here:</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2023-12-27-creating-an-ai-powered-financial-analyst_16.webp\"></p>\n<p>Since this is a deterministic workflow, we can look at the raw data to check whether the output is correct or not - which we can validate below.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2023-12-27-creating-an-ai-powered-financial-analyst_17.webp\"></p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"prompt-b\">Prompt B<a href=\"https://didierlopes.com/blog/creating-an-ai-powered-financial-analyst#prompt-b\" class=\"hash-link\" aria-label=\"Direct link to Prompt B\" title=\"Direct link to Prompt B\">​</a></h3>\n<p><em>\"Perform a fundamentals financial analysis of AMZN using the most recently available data. What do you find that's interesting?\"</em></p>\n<p>The output can be seen here:</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2023-12-27-creating-an-ai-powered-financial-analyst_18.webp\"></p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2023-12-27-creating-an-ai-powered-financial-analyst_19.webp\"></p>\n<p>As can be seen above, the results are extremely impressive. We achieved this with a couple of weeks of work, but there are still a lot of areas that we can improve and in which we are currently working on. However, the current results make this an extremely exciting space to be.</p>\n<p>All this work is open source and can be found on GitHub <a href=\"https://github.com/OpenBB-finance/openbb-agents\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<p>We are just getting started.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/creating-an-ai-powered-financial-analyst",
            "title": "Creating an AI-powered financial analyst",
            "summary": "Our Platform aims to empower the OpenBB Copilot, an AI-powered financial analyst, to perform tasks ranging from knowledge retrieval to fully autonomous analysis. The architecture involves task decomposition, tool retrieval, and subtask agents, showcasing impressive results in both deterministic and non-deterministic workflows. Read on to explore its capabilities and don't forget to watch the demos.",
            "date_modified": "2023-12-27T00:00:00.000Z",
            "tags": [
                "openbb",
                "ai",
                "llm",
                "agents",
                "copilot",
                "function-calling",
                "pydantic",
                "langchain"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/the-new-finai-tech-stack",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2023-12-15-the-new-finai-tech-stack.webp\"></p>\n<br>\n<p>This blog post delves into how our collaboration with MindsDB, Nixtla, LlamaIndex, and Langchain is revolutionizing the financial world. Read on to learn all about the event \"The New FinAI Tech Stack\" held last week in SF, California.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"context\">Context<a href=\"https://didierlopes.com/blog/the-new-finai-tech-stack#context\" class=\"hash-link\" aria-label=\"Direct link to Context\" title=\"Direct link to Context\">​</a></h2>\n<p>In early September, I attended a “Future of Finance” event in NYC. Despite the presence of well-known financial professionals from top firms in the industry, I found the event lacked practical applications demonstrating how AI is impacting the financial sector.</p>\n<p>Once I was back in the Bay Area, I had a barbecue with Jorge and Max from MindsDB and Nixtla, and I was commenting on that experience. To which Jorge promptly replied - why don’t we do it ourselves? So following this discussion, we decided to put the AI in finance event in motion.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2023-12-15-the-new-finai-tech-stack_1.webp\"></p>\n<p>At OpenBB, AI has become a key component in our approach to refactoring the OpenBB Platform from the ground up. We've recently recruited a Head of AI to help us build our strategy and work on this effort full-time.</p>\n<p>You can find more details on this <a href=\"https://didierlopes.com/blog/revolutionizing-ai-at-openbb-with-new-leader-michael-struwig\">here</a>.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2023-12-15-the-new-finai-tech-stack_2.webp\"></p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"openbb-x-mindsdb\">OpenBB x MindsDB<a href=\"https://didierlopes.com/blog/the-new-finai-tech-stack#openbb-x-mindsdb\" class=\"hash-link\" aria-label=\"Direct link to OpenBB x MindsDB\" title=\"Direct link to OpenBB x MindsDB\">​</a></h2>\n<p>A few days later, I visited the MindsDB office to discuss collaborating with Jorge on potential partnerships. I suggested the idea of gaining access to MindsDB's data, a proposal that seemed feasible to implement.</p>\n<p>Eventually, we accomplished this, and I even showcased it during the event last week. The code for this endeavour is open source. Take a look <a href=\"https://github.com/OpenBB-finance/backend-for-terminal-pro/tree/main/mindsdb_python\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<video controls=\"\"><source src=\"https://openbb-cms.directus.app/assets/bbc1b3c9-2617-46a1-aae6-f41cfd4d3745\"></video>\n<p>However, Jorge had an even bigger idea. He proposed the concept of granting MindsDB users access to OpenBB data via SQL and harnessing MindsDB's capabilities for machine learning. Essentially, we could convert the data frame in runtime into a virtual SQL table, since we have access to the Pydantic model from the OpenBB platform, and we can build that on the go.</p>\n<p>After <a href=\"https://twitter.com/didier_lopes/status/1710560436398264756?s=20\" target=\"_blank\" rel=\"noopener noreferrer\">tweeting about this</a>, I received numerous messages, which validated that there was interest in OBB SQL. So, we set off to work on this. Together with the OpenBB team, we made it easy to access all available inputs/outputs for each endpoint, while the MindsDB team worked on virtualizing the tables. The result can be seen <a href=\"https://github.com/mindsdb/mindsdb/tree/staging/mindsdb/integrations/handlers/openbb_handler\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<p>At the event last week, Jorge shared this work. Additionally, in collaboration with LangChain, he successfully developed a Slack bot with direct access to this data, all accessible within Slack</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"openbb-x-nixtla\">OpenBB x Nixtla<a href=\"https://didierlopes.com/blog/the-new-finai-tech-stack#openbb-x-nixtla\" class=\"hash-link\" aria-label=\"Direct link to OpenBB x Nixtla\" title=\"Direct link to OpenBB x Nixtla\">​</a></h2>\n<p>Back in August, Nixtla introduced the initial foundation generative AI model for temporal data at MindsDB. At that time, we received an invitation to showcase the practical applications of TimeGPT in production, and for the first time, we unveiled Terminal Pro briefly.</p>\n<p>I detailed this experience in a <a href=\"https://openbb.co/blog/openbb-incorporates-the-first-generative-AI-model-for-temporal-data-timegpt\" target=\"_blank\" rel=\"noopener noreferrer\">blog post</a> and shared a similar demo during the event last week.</p>\n<video controls=\"\"><source src=\"https://openbb-cms.directus.app/assets/a8a391c9-33e8-4c6b-821c-620617d4fe33\"></video>\n<p>Following that, Max and Azul from Nixtla proceeded to share a presentation where they used OpenBB data to assess price targets from analysts and develop an approach on how it is possible to reduce the bias inherent to price estimates and produce better estimates.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"openbb-x-llamaindex\">OpenBB x LlamaIndex<a href=\"https://didierlopes.com/blog/the-new-finai-tech-stack#openbb-x-llamaindex\" class=\"hash-link\" aria-label=\"Direct link to OpenBB x LlamaIndex\" title=\"Direct link to OpenBB x LlamaIndex\">​</a></h2>\n<p>Back in July, we initiated the development of AskOBB, enabling users to interact with the open source <a href=\"https://github.com/OpenBB-finance/OpenBBTerminal\" target=\"_blank\" rel=\"noopener noreferrer\">OpenBB Terminal</a> using natural language. In this effort, we leveraged LlamaIndex and you can see more about it <a href=\"https://openbb.co/blog/breaking-barriers-with-openbb-and-llamaIndex\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<p>So when we started discussing an AI in Finance event, it only made sense to reach out to Jerry and Simon to invite their team to present at the event. And so we did. Jerry ended up presenting their <a href=\"https://github.com/run-llama/sec-insights\" target=\"_blank\" rel=\"noopener noreferrer\">open source SEC insights repo</a> that uses the Retrieval Augmented Generation (RAG) capabilities of LlamaIndex to answer questions about SEC 10-K &amp; 10-Q documents.</p>\n<p>As for the OpenBB Terminal Pro, we demonstrated how we are using LlamaIndex to chat with documents that are uploaded to the OpenBB Terminal Pro. The video below highlights these features.</p>\n<video controls=\"\"><source src=\"https://openbb-cms.directus.app/assets/3c4190be-2676-4790-a59e-c33c6006a195\"></video>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"openbb-x-langchain\">OpenBB x Langchain<a href=\"https://didierlopes.com/blog/the-new-finai-tech-stack#openbb-x-langchain\" class=\"hash-link\" aria-label=\"Direct link to OpenBB x Langchain\" title=\"Direct link to OpenBB x Langchain\">​</a></h2>\n<p>After attending the AI Engineering Summit event, specifically Harrison’s workshop on how to get started with agents using Langchain, I felt inspired to create an agent on top of the OpenBB platform.</p>\n<p>So that very day, I went home and started to work on <a href=\"https://github.com/DidierRLopes/openbb-agents\" target=\"_blank\" rel=\"noopener noreferrer\">this repo</a>. By the end of the day, the agent was already able to perform complex queries.</p>\n<p>Over time I iterated on it to make the agent more robust, but the improvement on the architecture started to happen after Michael joined OpenBB and he was able to focus on this full-time - the progress can be found on <a href=\"https://github.com/OpenBB-finance/openbb-agents\" target=\"_blank\" rel=\"noopener noreferrer\">this open source repo</a>. An example of a prompt that the agent can answer is:</p>\n<blockquote>\n<p><em>Check what are TSLA peers. From those, check which one has the highest market cap. Then, on the ticker that has the highest market cap get the most recent price target estimate from an analyst, and tell me who it was and on what date the estimate was made.</em></p>\n</blockquote>\n<br>\n<p>So at the event, Harrison presented this architecture which heavily relies on Langchain and OpenBB tools.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2023-12-15-the-new-finai-tech-stack_3.webp\"></p>\n<p>Later on, I demonstrated how we can integrate this architecture into OpenBB Copilot and make it available from the OpenBB Terminal Pro.</p>\n<video controls=\"\"><source src=\"https://openbb-cms.directus.app/assets/a3c20953-ca08-4bdd-b7d5-93878edc7e07\"></video>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"wrap-up\">Wrap up<a href=\"https://didierlopes.com/blog/the-new-finai-tech-stack#wrap-up\" class=\"hash-link\" aria-label=\"Direct link to Wrap up\" title=\"Direct link to Wrap up\">​</a></h2>\n<p>Finally, this was an amazing event organized by MindsDB and a team that put together 5 of the most prominent open-source companies working on problems at the intersection of AI and Finance.</p>\n<p>You can rewatch the entire event here:</p>\n<div class=\"flex place-items-center justify-center items-center rounded-sm mx-auto\"><iframe src=\"https://www.youtube.com/embed/V1rYmWWVbIY?si=25HUWPxjAB8sfUPx\" width=\"800\" height=\"400\"></iframe></div>\n<br>\n<p>We're considering organizing another event like this soon, possibly even in NYC.</p>\n<p>And if your firm is interested in early access to the OpenBB Terminal Pro, you can reach out to <a href=\"mailto:hello@openbb.finance\" target=\"_blank\" rel=\"noopener noreferrer\">hello@openbb.finance</a>, we’d love to chat.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/the-new-finai-tech-stack",
            "title": "The new FinAI Tech Stack",
            "summary": "This blog post delves into how our collaboration with MindsDB, Nixtla, LlamaIndex, and Langchain is revolutionizing the financial world. Read on to learn all about the event \"The New FinAI Tech Stack\" held last week in SF, California.",
            "date_modified": "2023-12-15T00:00:00.000Z",
            "tags": [
                "openbb",
                "finance",
                "ai",
                "agents",
                "langchain",
                "llamaindex",
                "mindsdb",
                "nixtla"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/goodbye-openbb-sdk-hello-openbb-platform",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2023-11-29-goodbye-openbb-sdk-hello-openbb-platform.webp\"></p>\n<br>\n<p>Today, we are thrilled to announce the new OpenBB SDK, a game-changing platform that is now divided into the robustness of OpenBB Core and the limitless potential of OpenBB extensions.</p>\n<p>The open source code is available <a href=\"https://github.com/OpenBB-finance/OpenBBTerminal\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>In the ever-evolving landscape of financial data integration and standardization, OpenBB has been revolutionizing the way individuals and organizations handle data from multiple data providers by utilizing our open-source products.</p>\n<p>We have been talking about the OpenBB Platform v4 over the past few months. This is such a milestone for our team and for the financial world that we are renaming the OpenBB SDK into the OpenBB Platform.</p>\n<p>The OpenBB Platform consists of the OpenBB Core and OpenBB Extensions.</p>\n<p>Let’s dive into each of these, individually.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"openbb-core\">OpenBB Core<a href=\"https://didierlopes.com/blog/goodbye-openbb-sdk-hello-openbb-platform#openbb-core\" class=\"hash-link\" aria-label=\"Direct link to OpenBB Core\" title=\"Direct link to OpenBB Core\">​</a></h2>\n<p>The OpenBB Core empowers quants and finance developers to create powerful data solutions, offering unparalleled simplicity, flexibility, and scalability. It follows the principle that \"less is more.\"</p>\n<p>The core will consist of two main components:</p>\n<ol>\n<li>\n<p><strong>Data Standardization Infrastructure:</strong> This ensures that regardless of the type of data processed by the core, users can expect consistent conventions and naming. This facilitates a seamless experience, even when the data comes from completely different data providers.</p>\n</li>\n<li>\n<p><strong>Data Source Integration:</strong> Developers will be able to effortlessly connect and integrate various data sources, including databases, APIs, and cloud storage systems.</p>\n<p>a) <strong>Official partner integrations</strong> will be available by having access to official endpoints from data vendors. This ensures the integrity of the data and provides a reference for what data is available to the end user. Our affiliate program will detail where commercial agreements are in place with OpenBB.</p>\n<p>b) Additionally, <strong>community provider integrations</strong> will be available, allowing the community to contribute their own integrations for specific use cases or share them with others through the open-source codebase.</p>\n</li>\n</ol>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"openbb-extensions\">OpenBB Extensions<a href=\"https://didierlopes.com/blog/goodbye-openbb-sdk-hello-openbb-platform#openbb-extensions\" class=\"hash-link\" aria-label=\"Direct link to OpenBB Extensions\" title=\"Direct link to OpenBB Extensions\">​</a></h2>\n<p>OpenBB extensions enhance the capabilities of the OpenBB Core, allowing developers to create custom functionalities and customize the overall Platform according to their specific needs. It is important to note that these extensions can be used as a standalone or integrated with the rest of the openBB ecosystem.</p>\n<p>These extensions can be classified into two categories:</p>\n<ul><li><strong>Official extensions</strong> developed and maintained by the OpenBB Team, such as the ML/AI Toolkit, Econometrics, and Reports;</li><li><strong>Community extensions</strong> developed by the open-source community. These extensions focus on enabling intelligent data processing and custom workflows that assist users in their investing decision-making process.</li></ul>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"key-advantage-of-new-platform-v4\">Key advantage of new platform V4<a href=\"https://didierlopes.com/blog/goodbye-openbb-sdk-hello-openbb-platform#key-advantage-of-new-platform-v4\" class=\"hash-link\" aria-label=\"Direct link to Key advantage of new platform V4\" title=\"Direct link to Key advantage of new platform V4\">​</a></h2>\n<p>By combining the strengths of OpenBB Core and OpenBB Extensions, the OpenBB Platform offers unparalleled advantages for developers and organizations:</p>\n<ol><li><strong>Enhanced Flexibility:</strong> The modular architecture of the Platform allows developers to choose and integrate only the components they need, avoiding unnecessary complexity.</li><li><strong>Scalability:</strong> The OpenBB Platform seamlessly scales with your data integration requirements, ensuring smooth performance even with large volumes of data.</li><li><strong>Extensibility:</strong> Developers can create their own extensions and contribute to the OpenBB ecosystem, fostering collaboration and innovation.</li><li><strong>Time and Cost Savings:</strong> With its intuitive interface and pre-built components, the OpenBB Platform accelerates development cycles, reducing time-to-market and costs associated with custom solutions.</li></ol>\n<br>\n<p>The reimagined OpenBB SDK into OpenBB Platform (OpenBB Core and OpenBB Extensions), revolutionizes the data integration landscape.</p>\n<p>By leveraging the power of OpenBB Core for data integration and standardization, and harnessing the capabilities of OpenBB Extensions for customization and advanced functionality, developers can unlock new possibilities and build cutting-edge data solutions.</p>\n<p>Whether you are working with diverse data sources or performing complex data transformations, the OpenBB Platform empowers you to conquer any data challenge and propel your organization towards data-driven success.</p>\n<p>We invite users and enthusiasts to explore the OpenBB Platform v4, now available for download and installation from the <a href=\"https://docs.openbb.co/platform/installation\" target=\"_blank\" rel=\"noopener noreferrer\">OpenBB Hub</a>, <a href=\"https://github.com/OpenBB-finance/OpenBBTerminal/tree/develop/openbb_platform\" target=\"_blank\" rel=\"noopener noreferrer\">Github</a>, and <a href=\"https://pypi.org/project/openbb/\" target=\"_blank\" rel=\"noopener noreferrer\">PyPI</a>.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"inside-openbb-a-peek-into-our-team-emails\">Inside OpenBB: A peek into our team emails<a href=\"https://didierlopes.com/blog/goodbye-openbb-sdk-hello-openbb-platform#inside-openbb-a-peek-into-our-team-emails\" class=\"hash-link\" aria-label=\"Direct link to Inside OpenBB: A peek into our team emails\" title=\"Direct link to Inside OpenBB: A peek into our team emails\">​</a></h2>\n<p>In order to adhere to one of OpenBB's core values - Transparency - we want you to understand the journey we have undergone and the reason we have dedicated the past 9 months to this endeavor.</p>\n<p>So, for the first time, we're sharing a confidential email thread that circulated among our entire team. This thread provides insight into our thought process when it comes to handling large projects at OpenBB.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2023-11-29-goodbye-openbb-sdk-hello-openbb-platform_1.webp\"></p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2023-11-29-goodbye-openbb-sdk-hello-openbb-platform_2.webp\"></p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2023-11-29-goodbye-openbb-sdk-hello-openbb-platform_3.webp\"></p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2023-11-29-goodbye-openbb-sdk-hello-openbb-platform_4.webp\"></p>\n<p>Over the next few weeks we will keep iterating on our Platform, based on user feedback, so we can keep pushing for a platform that can be adopted by everyone - from professional investors, data scientists, quants, to students.</p>\n<p>If you rely on financial data to do financial research or build apps, we want to hear from you!</p>\n<p>Reach out with feedback to <a href=\"mailto:support@openbb.finance\" target=\"_blank\" rel=\"noopener noreferrer\">support@openbb.finance</a> or join <a href=\"https://discord.com/invite/xPHTuHCmuV\" target=\"_blank\" rel=\"noopener noreferrer\">our Discord</a>.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/goodbye-openbb-sdk-hello-openbb-platform",
            "title": "Goodbye OpenBB SDK. Hello OpenBB Platform",
            "summary": "Today, we are thrilled to announce the new OpenBB SDK, a game-changing platform that is now divided into the robustness of OpenBB Core and the limitless potential of OpenBB extensions.",
            "date_modified": "2023-11-29T00:00:00.000Z",
            "tags": [
                "openbb",
                "platform",
                "sdk",
                "core",
                "extensions"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/openbb-bot-our-new-addition-to-the-openbb-open-source-family",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2023-11-21-openbb-bot-our-new-addition-to-the-openbb-open-source-family.webp\"></p>\n<br>\n<p>The OpenBB Bot is now open source. Check out our Discord Bot architecture now on GitHub.</p>\n<p>The open source code is available <a href=\"https://github.com/OpenBB-finance/openbb-bot\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"what-is-the-openbb-bot-and-why-did-we-build-it\">What is the OpenBB Bot, and why did we build it?<a href=\"https://didierlopes.com/blog/openbb-bot-our-new-addition-to-the-openbb-open-source-family#what-is-the-openbb-bot-and-why-did-we-build-it\" class=\"hash-link\" aria-label=\"Direct link to What is the OpenBB Bot, and why did we build it?\" title=\"Direct link to What is the OpenBB Bot, and why did we build it?\">​</a></h2>\n<p>When the OpenBB Terminal first went viral, users were writing online that one of the things missing from our product was a chat feature like other investment platforms provide.</p>\n<p>However, we didn't understand why the chatting experience needed to be centralized in the application where users research their financial data. Plus, with the ever-growing userbase of apps like Discord, Telegram, Slack, and others, combined with their capabilities to build apps on top, we thought we could do more.</p>\n<p>We believe in a future where you can query financial data right from where you are. Meaning you can chat with colleagues, from any of the apps you're already using.</p>\n<p>This is when we partnered with OptionsFamBot (the biggest Discord financial bot that was present in 15k+ servers, reaching 1 M+ users) to build the OpenBB Bot.</p>\n<p>You can read more about our launch in August 2022 <a href=\"https://openbb.co/blog/openbb-bot-launch\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"failing-to-monetize-failing-to-grow-user-base\">Failing to monetize. Failing to grow user base.<a href=\"https://didierlopes.com/blog/openbb-bot-our-new-addition-to-the-openbb-open-source-family#failing-to-monetize-failing-to-grow-user-base\" class=\"hash-link\" aria-label=\"Direct link to Failing to monetize. Failing to grow user base.\" title=\"Direct link to Failing to monetize. Failing to grow user base.\">​</a></h2>\n<p>To provide OpenBB Bot users with access to 100+ financial commands (including expensive datasets such as the options and dark pool ones) we had to pay not just the data vendors but also for the display rights.</p>\n<p>This was relatively expensive, but we considered it a marketing cost since we expected exponential user growth. We expected that since the Bot could be deployed in any server in a few seconds, more users would be exposed to the Bot, bringing the Bot to other servers, and so on...</p>\n<p><strong>However, that didn't happen.</strong></p>\n<p>In September 2022, Discord changed its command syntax to force commands to start with \"/\" and the user drop was noticeable.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2023-11-21-openbb-bot-our-new-addition-to-the-openbb-open-source-family_1.webp\"></p>\n<p>In the meantime, with the end of the Covid-19 Pandemic, people started leaving their houses more and spending less time with communities investing online. Other companies with financial bots were experiencing the same: investors spending less time talking about investing on apps like Discord.</p>\n<p>We saw a trend that these same companies started increasing their prices to balance out the number of users.</p>\n<p>This is when we went in the other direction: we upgraded our free tier package and decreased the price of our paid version. That announcement can be found <a href=\"https://openbb.co/blog/openbb-bot-price-change\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2023-11-21-openbb-bot-our-new-addition-to-the-openbb-open-source-family_2.webp\"></p>\n<p>This happened at the same time as we added more innovative features to the bot. Features that OpenBB brought to market, while other bots copied from us today.</p>\n<p>We created a codebase that was robust and scalable, but still flexible so that it could be quickly tweaked and deployed on other chatting apps.</p>\n<p>A couple of days after the price reduction, we announced OpenBB Bot for Telegram (read more about this announcement <a href=\"https://openbb.co/blog/openbb-bot-arrives-on-telegram\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>).</p>\n<p>With the growth of Telegram users and crypto communities, we were well posed to capture that market.</p>\n<p>Or so we thought. But our growth never achieved the numbers we had initially estimated.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2023-11-21-openbb-bot-our-new-addition-to-the-openbb-open-source-family_3.webp\"></p>\n<p>Our conclusion is that the market for financial chatbots is much smaller than what we had originally forecasted. This also meant that our goal with the OpenBB Bot as a marketing tool wasn't returning the ROI that we were expecting.</p>\n<p>So in May 2023 we went pretty much all-in on considering the OpenBB Bot as a marketing expense, and removed the individual paid tier. You can see that announcement <a href=\"https://openbb.co/blog/openbb-bot-free-for-individuals\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2023-11-21-openbb-bot-our-new-addition-to-the-openbb-open-source-family_4.webp\"></p>\n<p>Note that we maintained the control of the Billboard message. This is a feature that allows us to add OpenBB events and announcements to the top of these commands, hence increasing awareness. See below how it looks,</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2023-11-21-openbb-bot-our-new-addition-to-the-openbb-open-source-family_5.webp\"></p>\n<p>However, even with that change and <a href=\"https://openbb.co/blog/openbb-midjourney-for-investing\" target=\"_blank\" rel=\"noopener noreferrer\">adding an AI feature</a> to the OpenBB Bot, the user base never grew past what we had hoped.</p>\n<p>So we decided to open source the architecture behind the OpenBB Bot.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"decision-to-open-source\">Decision to open source<a href=\"https://didierlopes.com/blog/openbb-bot-our-new-addition-to-the-openbb-open-source-family#decision-to-open-source\" class=\"hash-link\" aria-label=\"Direct link to Decision to open source\" title=\"Direct link to Decision to open source\">​</a></h2>\n<p>When talking with Roberto Talamas (check out his <a href=\"https://openbb.co/blog/openbb-champions-roberto-talamas\" target=\"_blank\" rel=\"noopener noreferrer\">OpenBB champion story</a>), he mentioned that he was building his own financial chatbot for his fund from scratch.</p>\n<p>That was the trigger we needed to open source our architecture, so the \"Robertos\" of the world wouldn't have to start building their chatbot from scratch, but could piggyback on our architecture, which just works (it has never been down since launch and processed over 2.75 M Discord requests).</p>\n<p>Since we failed to monetize the Bot, and our adoption trajectory never grew past our expectations, open-sourcing the architecture behind the OpenBB Bot made a ton of sense.</p>\n<p>This architecture utilizes data from the OpenBB platform (check out last week's <a href=\"https://openbb.co/blog/celebrating-the-openbb-platform-v4-beta\" target=\"_blank\" rel=\"noopener noreferrer\">beta announcement</a>) which means that developers can simultaneously get familiar with our platform while seeing how easy it is to pull financial data from OpenBB - effectively growing OpenBB's ecosystem.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2023-11-21-openbb-bot-our-new-addition-to-the-openbb-open-source-family_6.webp\"></p>\n<p>I'm looking forward to seeing what products are built around the OpenBB Bot in the future.</p>\n<p>You can check the repository <a href=\"https://github.com/OpenBB-finance/openbb-bot\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<p>Welcome to the OpenBB open source family.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/openbb-bot-our-new-addition-to-the-openbb-open-source-family",
            "title": "OpenBB Bot - our new addition to the OpenBB open source family",
            "summary": "The OpenBB Bot architecture is now open source. Check out our Discord Bot architecture now on GitHub.",
            "date_modified": "2023-11-21T00:00:00.000Z",
            "tags": [
                "openbb",
                "openbb-bot",
                "open-source",
                "discord",
                "telegram",
                "chatbots",
                "monetization",
                "business-strategy",
                "product-story"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/revolutionizing-ai-at-openbb-with-new-leader-michael-struwig",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2023-11-07-revolutionizing-ai-at-openbb-with-new-leader-michael-struwig.webp\"></p>\n<br>\n<p>With the launch of the OpenBB Terminal Pro approaching, we're excited to announce the hiring of Michael Struwig, a Ph.D. with expertise in AI and quantitative finance. Michael will help us to further our AI capabilities, reinforcing our commitment to innovation in the open-source finance space.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>AI will be one of the technologies that will be looked back in hundreds of years as revolutionary, changing how humans live.</p>\n<p>With the upcoming launch of the <a href=\"https://my.openbb.co/app/pro\" target=\"_blank\" rel=\"noopener noreferrer\">OpenBB Terminal Pro</a>, we believe AI can push the limits of the way users do investment research.</p>\n<p>We believe our ecosystem is positioned at the forefront of finance in terms of investment research. With the inception of the OpenBB Terminal Pro, we are standing at the cusp of a significant leap. Our journey began with <a href=\"https://openbb.co/blog/breaking-barriers-with-openbb-and-llamaIndex\" target=\"_blank\" rel=\"noopener noreferrer\">AskOBB</a>, a tool that facilitated natural language interaction with financial data, but that was just the start.</p>\n<p>Last month, I wrote a <a href=\"https://twitter.com/didier_lopes/status/1706731145776566399\" target=\"_blank\" rel=\"noopener noreferrer\">tweet</a> explaining why we spent over $500,000 in revamping our core platform. We are committed to creating the best finance platform for quants/analysts to build with. Some key features are:</p>\n<ul><li>We are data vendor agnostic - we enable them</li><li>We are open source - everyone can contribute data</li><li>We standardize data across close to 100 different data providers</li><li>We put a lot of effort into our documentation</li></ul>\n<p>These features allow us to bring AI to our platform from the ground up, and think about how that will impact the user experience at the core level.</p>\n<p>For instance this is an extension that James added to the OpenBB Platform.</p>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2023-11-07-revolutionizing-ai-at-openbb-with-new-leader-michael-struwig_1.webp\"></p>\n<p>There are a lot of products out there utilizing generative AI for finance. Most of these can be classified as:</p>\n<ul><li>Startups built around a particular feature - e.g. chatting with news. With LLMs becoming a commodity, over time it will be easy to understand that this is a feature and not a product itself.</li><li>Larger companies that put a small team together to explore generative AI to be seen as leaders in the space - but without an intention to bring such to market. Often because of outdated tech stack.</li></ul>\n<p>We are different. The <a href=\"https://my.openbb.co/app/pro\" target=\"_blank\" rel=\"noopener noreferrer\">OpenBB Terminal Pro</a> is the most customizable investment research platform for teams of quants and analysts. It contains generative AI features, but these are embodied inside the app, and treated as part of the user experience.</p>\n<p>Some examples below:</p>\n<li>Summarize news articles in seconds</li>\n<br>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2023-11-07-revolutionizing-ai-at-openbb-with-new-leader-michael-struwig_2.webp\"></p>\n<li>Ask more detailed questions to your widgets like earnings transcript or even insider trading</li>\n<br>\n<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2023-11-07-revolutionizing-ai-at-openbb-with-new-leader-michael-struwig_3.webp\"></p>\n<li>And more.</li>\n<br>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>Most of these generative AI features have been started as side projects by our team members, and once we validated the use case with financial professionals we incorporated it into the roadmap. However, we want to double down on this effort and therefore we're excited to welcome <a href=\"https://twitter.com/MichaelNStruwig\" target=\"_blank\" rel=\"noopener noreferrer\">Michael</a> to OpenBB.</p>\n<p><a href=\"https://twitter.com/MichaelNStruwig\" target=\"_blank\" rel=\"noopener noreferrer\">Michael</a> has a PhD in Electrical and Electronic Engineering, has been doing AI for a few years, and prior to joining us was the CEO of Hudson &amp; Thames Quantitative Research.</p>\n<p>I first heard him from his reading groups:</p>\n<div class=\"flex place-items-center justify-center items-center rounded-sm mx-auto\"><iframe width=\"619\" height=\"400\" src=\"https://www.youtube.com/embed/FxMDrHnKWnk\" title=\"BloombergGPT: A Large Language Model for Finance\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\"></iframe></div>\n<br>\n<div class=\"flex place-items-center justify-center items-center rounded-sm mx-auto\"><iframe width=\"619\" height=\"400\" src=\"https://www.youtube.com/embed/kX_7ocfTS8g\" title=\"FinGPT: Open-Source Financial Large Language Models\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\"></iframe></div>\n<p>From watching these videos it was clear that Michael is an expert in the field and was capable of understanding deep topics and not solely staying on the surface. So I was keen to have a chat with him. It turns out that he was a big supporter of OpenBB in particular due to our open-source approach to finance and the connection was immediate.</p>\n<p>Michael met a few of our team members, and a week later we had a signed contract.</p>\n<p>I couldn’t be more excited to welcome him to the team and see the amazing products we are going to build at OpenBB.</p>\n<p>Here’s what Michael has to say about joining OpenBB:</p>\n<blockquote>\n<p><em>\"At OpenBB, I've discovered the perfect blend of my core passions: ML/AI, Opensource, and, more recently, quantitative finance. Joining the OpenBB team truly feels like a fairytale come true. I've never encountered a team so singularly-focused and driven. They genuinely \"get it,\" and working alongside such talented individuals is incredibly inspiring. I'm ecstatic to be on board and am eager to help contribute to OpenBB's AI initiatives.\"</em></p>\n</blockquote>\n<br>\n<p>If you are excited about the field of open source, AI, and finance, and want to help - you can reach out to Michael on <a href=\"https://twitter.com/MichaelNStruwig\" target=\"_blank\" rel=\"noopener noreferrer\">Twitter</a>.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/revolutionizing-ai-at-openbb-with-new-leader-michael-struwig",
            "title": "Revolutionizing AI at OpenBB with new leader, Michael Struwig",
            "summary": "With the launch of the OpenBB Terminal Pro approaching, we're excited to announce the hiring of Michael Struwig, a Ph.D. with expertise in AI and quantitative finance. Michael will help us to further our AI capabilities, reinforcing our commitment to innovation in the open-source finance space.",
            "date_modified": "2023-11-07T00:00:00.000Z",
            "tags": [
                "ai",
                "openbb",
                "startup",
                "finance",
                "hiring"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/writing-documentation-as-a-founder-is-underrated",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2023-10-29-writing-documentation-as-a-founder-is-underrated.webp\"></p>\n<br>\n<p>This blog post emphasizes the importance of writing documentation as a founder. It discusses how it can give an edge when pitching your product and how it can result in less customer support and a better user experience overall.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>A founder spending time writing documentation is f*king underrated.</p>\n<p>Working on your product documentation may not be the most rewarding task, but I strongly believe that it gives you an edge when pitching your product.</p>\n<p>Good documentation needs to strike the perfect balance between having enough context and being straight to the point.</p>\n<p>This week someone asked us how many people worked on our documentation.</p>\n<p>There have been less than 3 people working on it. Our North Star metric has been common sense and putting out documentation that we would enjoy reading/learning from ourselves.</p>\n<p>Earlier this year I also heard suggestions of hiring a dedicated technical writer.</p>\n<p>I think that’s BS, at least at the early stages of your company.</p>\n<p>It’s the equivalent of saying that you should hire someone to tell your company vision or that the first sales shouldn’t come from the founders.</p>\n<p>No one knows your product better than yourself. And users (particularly devs) will notice the love put into documentation. + This will result in less customer support and a better user experience overall.</p>\n<p>Honestly, a very underrated task if you ask me.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/writing-documentation-as-a-founder-is-underrated",
            "title": "Writing documentation, as a founder, is underrated.",
            "summary": "This blog post emphasizes the importance of writing documentation as a founder. It discusses how it can give an edge when pitching your product and how it can result in less customer support and a better user experience overall.",
            "date_modified": "2023-10-29T00:00:00.000Z",
            "tags": [
                "documentation",
                "founder",
                "startup",
                "writing",
                "product"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/building-the-worlds-investment-research-infrastructure",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2023-10-19-building-the-worlds-investment-research-infrastructure.webp\"></p>\n<br>\n<p>This blog post discusses the process and challenges of building the world's investment research infrastructure. It provides an insight into the products developed by the OpenBB team and their efficient operation.</p>\n<p>The open source code is available <a href=\"https://github.com/openbb-finance/OpenBBTerminal\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p><a href=\"http://openbb.co/\" target=\"_blank\" rel=\"noopener noreferrer\">OpenBB</a> team is comprised of 18 FTE.</p>\n<p>We have 8 products: <a href=\"https://my.openbb.co/app/platform\" target=\"_blank\" rel=\"noopener noreferrer\">OpenBB Platform</a>, <a href=\"https://my.openbb.co/app/terminal\" target=\"_blank\" rel=\"noopener noreferrer\">OpenBB Terminal</a>, <a href=\"https://my.openbb.co/app/bot\" target=\"_blank\" rel=\"noopener noreferrer\">OpenBB Bot</a>, <a href=\"https://my.openbb.co/app/pro\" target=\"_blank\" rel=\"noopener noreferrer\">OpenBB Terminal Pro</a>, OpenBB Excel Add-In, <a href=\"https://my.openbb.co/app/hub\" target=\"_blank\" rel=\"noopener noreferrer\">OpenBB Hub</a>, <a href=\"https://docs.openbb.co/\" target=\"_blank\" rel=\"noopener noreferrer\">OpenBB Docs</a> and <a href=\"https://openbb.co/\" target=\"_blank\" rel=\"noopener noreferrer\">Marketing website</a>.</p>\n<p>This means that on average we have around 2 people working on each product.</p>\n<p>This is particularly wild when you look into the complexity associated with each of these products and being at the forefront of innovation.</p>\n<p>That average includes not only engineers but design, product, and marketing.</p>\n<p>In addition, our <a href=\"https://openbb.co/discord\" target=\"_blank\" rel=\"noopener noreferrer\">Discord community</a> has 14k+ people and we often get praised regarding how good our support is.</p>\n<p>Regardless of our future, I am proud of the team we put together and how efficiently we operate.</p>\n<p>It would take a much larger company well over 5 years to build what we built in 2.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/building-the-worlds-investment-research-infrastructure",
            "title": "Building the world’s investment research infrastructure",
            "summary": "This blog post discusses the process and challenges of building the world's investment research infrastructure. It provides an insight into the products developed by the OpenBB team and their efficient operation.",
            "date_modified": "2023-10-19T00:00:00.000Z",
            "tags": [
                "investment",
                "research",
                "infrastructure",
                "openbb"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/a-500k-bet-to-build-the-best-platform-to-do-ai-using-financial-data",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2023-10-14-a-500k-bet-to-build-the-best-platform-to-do-ai-using-financial-data.webp\"></p>\n<br>\n<p>This blog post discusses our $500k investment in building the best platform for AI using financial data. We focus on the rebranding of OpenBB SDK to OpenBB Platform, its features, and the potential payoff of this bet in 2024.</p>\n<p>The open source code is available <a href=\"https://github.com/DidierRLopes/openbb-agents/tree/main\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>Earlier this year we made a $500k bet.</p>\n<p>The <a href=\"https://my.openbb.co/app/sdk\" target=\"_blank\" rel=\"noopener noreferrer\">OpenBB SDK</a> had access to over 500 data endpoints. But it was built as a second thought (after the Terminal) and it was extremely time-consuming to manage all dependencies.</p>\n<p>Plus, the SDK had more than just access to data and thus was bloated.</p>\n<p>So we invested $500,000 to build it from the ground up and focus on data access.</p>\n<p>Now the OpenBB Platform (rebrand) is lean and scalable.</p>\n<p>It can be used in Python (<code>pip install openbb==4.0.0a2</code>) but also for web development. More information <a href=\"https://pypi.org/project/openbb/\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<p>And honestly, is the door to financial data.</p>\n<p><strong>Why am I saying all this?</strong></p>\n<p>Because I predict that in 2024 this bet will have a massive payoff.</p>\n<p><strong>The reason?</strong></p>\n<p>Agents are going to be big.</p>\n<p>And when they are, financial firms that aren’t leveraging them are going to have to spend a lot of resources to make up for the lack of efficiency.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"enter-openbb-platform\">Enter OpenBB Platform<a href=\"https://didierlopes.com/blog/a-500k-bet-to-build-the-best-platform-to-do-ai-using-financial-data#enter-openbb-platform\" class=\"hash-link\" aria-label=\"Direct link to Enter OpenBB Platform\" title=\"Direct link to Enter OpenBB Platform\">​</a></h2>\n<ul>\n<li>We are data vendor agnostic (we enable them)</li>\n<li>We are open source (everyone can contribute data)</li>\n<li>We standardize data across close to 100 different data providers</li>\n<li>We put a lot of effort into our documentation</li>\n</ul>\n<p>The last 3 points are key for agents, and why people will build agents on top of the OpenBB platform.</p>\n<p>In a few hours, I was able to use the following prompt:</p>\n<div class=\"language-console codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-console codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    Check what are TSLA peers.</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    From those, check which one has the highest market cap. </span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    Then, on the ticker that has the highest market cap get </span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    the most recent rating from an analyst. And tell me who </span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    was the analyst and what date was it that the rating was done</span><br></span></code></pre></div></div>\n<p>To have an agent execute this entire workflow in a 1/10th of the time that it would have taken an analyst to do.</p>\n<p>Check for yourself the example below,</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2023-10-14-a-500k-bet-to-build-the-best-platform-to-do-ai-using-financial-data_1-452231b46e3efe4f9fba3d3bbdfd4ea0.webp\" width=\"2000\" height=\"1129\" class=\"img_ev3q\"></p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/a-500k-bet-to-build-the-best-platform-to-do-ai-using-financial-data",
            "title": "A $500k bet to build the best platform to do AI using financial data",
            "summary": "This blog post discusses our $500k investment in building the best platform for AI using financial data. We focus on the rebranding of OpenBB SDK to OpenBB Platform, its features, and the potential payoff of this bet in 2024.",
            "date_modified": "2023-10-14T00:00:00.000Z",
            "tags": [
                "ai",
                "financial-data",
                "openbb",
                "data-access",
                "agents"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/work-life-balance-is-bullsh-t",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2023-09-16-work-life-balance-is-bullsh-t.webp\"></p>\n<br>\n<p>This blog post challenges the concept of work-life balance, arguing that success often requires sacrifices in personal time and relationships. It suggests that true balance comes from finding joy in your work and surrounding yourself with like-minded individuals.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>For successful individuals, achieving a work-life balance is a luxury often associated with those born into wealth.</p>\n<p>Let me explain.</p>\n<p>There must be a clear inverse correlation between success (let's say measured by wealth) and the size of your circle of friends.</p>\n<p><strong>If you want to be at the top of a field, you must work hard.</strong></p>\n<p>End.</p>\n<p>Regardless of what BS people say about work-life balance.</p>\n<p>You may be lucky — right place right time kind of thing. But by default, you need to work hard to expand your luck's surface.</p>\n<p>And that means that you need to spend your personal time working harder, to be above average.</p>\n<p>Since time is limited you need to sacrifice time spent outside working hours, otherwise you will only be average.</p>\n<p>People will soon realize that in order to optimize for a successful career, cutting time spent with friends is a necessary evil.</p>\n<p>Plus, as you become older you'll prioritize physical health (which impacts your longevity + performance) and your relationship with your partner (which provides the most significant ROI in terms of happiness).</p>\n<p>So, I suggest 2 things:</p>\n<ul>\n<li>Work on a problem and in a space that you truly enjoy so you don't consider it work</li>\n<li>Build with people who share the same values as you so you consider them friends Once that happens, work-life balance means nothing.</li>\n</ul>\n<p>What's your take?</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/work-life-balance-is-bullsh-t",
            "title": "Work-life balance is bullsh*t",
            "summary": "This blog post challenges the concept of work-life balance, arguing that success often requires sacrifices in personal time and relationships. It suggests that true balance comes from finding joy in your work and surrounding yourself with like-minded individuals.",
            "date_modified": "2023-09-16T00:00:00.000Z",
            "tags": [
                "work-life-balance",
                "success",
                "career",
                "hard-work",
                "startup-culture",
                "philosophy",
                "hustle-culture"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/target-market-analysis-with-the-help-of-llms",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2023-09-10-target-market-analysis-with-the-help-of-llms.webp\"></p>\n<br>\n<p>This blog post provides a comprehensive guide on how to perform target market analysis for your company using LLMs. It includes a detailed explanation of the BCG Matrix and the GE McKinsey Matrix, and how these frameworks can be used to determine market attractiveness and competitive advantage.</p>\n<p>The open source code is available <a href=\"https://github.com/DidierRLopes/target-market-analysis/tree/main\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>After working on <a href=\"https://openbb.co/\" target=\"_blank\" rel=\"noopener noreferrer\">OpenBB</a> for over 2 years, we learned which markets to go after and which markets to ignore. You may think that this is intuition, but it’s actually the data that you gathered from talking with 100+ users and learning from others in the industry.</p>\n<p>However, people who don’t know your business as well as you do (new joiners, advisors, or investors), don’t understand why your target market is X and not Y. Hence, it’s important to backtrace your “experience” with data.</p>\n<p>This blog post will focus on how you can perform target market analysis for your company. I will provide the framework and the code to leverage OpenAI to speed up that research process. All of this will be replicable, and you can do it for your own company.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"context\">Context<a href=\"https://didierlopes.com/blog/target-market-analysis-with-the-help-of-llms#context\" class=\"hash-link\" aria-label=\"Direct link to Context\" title=\"Direct link to Context\">​</a></h2>\n<p>This framework is utilized for portfolio analysis in corporate strategy to analyze business units or product lines.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"bcg-matrix\">BCG Matrix<a href=\"https://didierlopes.com/blog/target-market-analysis-with-the-help-of-llms#bcg-matrix\" class=\"hash-link\" aria-label=\"Direct link to BCG Matrix\" title=\"Direct link to BCG Matrix\">​</a></h3>\n<p>Initially, BCG implemented its own framework, which you can read more about here. In a nutshell:</p>\n<p><em>It uses two variables: relative market share and the market growth rate. By combining these two variables into a matrix, a corporation can plot their business units accordingly and determine where to allocate extra (financial) resources, where to cash out and where to divest.</em></p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2023-09-10-target-market-analysis-with-the-help-of-llms_1-d290c30ea6c9e6c8690937e72999d330.webp\" width=\"380\" height=\"365\" class=\"img_ev3q\"></p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"ge-mckinsey-matrix\">GE McKinsey Matrix<a href=\"https://didierlopes.com/blog/target-market-analysis-with-the-help-of-llms#ge-mckinsey-matrix\" class=\"hash-link\" aria-label=\"Direct link to GE McKinsey Matrix\" title=\"Direct link to GE McKinsey Matrix\">​</a></h3>\n<p>Then, the GE McKinsey Matrix was invented, which you can read more about here. To put it briefly:</p>\n<p><em>It uses two variables: industry attractiveness and the competitive strength of a business unit. By combining these two variables into a matrix, a corporation can plot their business units accordingly and determine where to invest, where to hold their position, and where to harvest or divest.</em></p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2023-09-10-target-market-analysis-with-the-help-of-llms_2-a9e7372e22fb9c8f08ed894954f83f0c.webp\" width=\"650\" height=\"541\" class=\"img_ev3q\"></p>\n<p>As per the blog post, the main difference between these comes from the fact that the latter uses multiple factors that are combined to determine the measure of the two variables: industry attractiveness and competitive strength. Whereas the BCG Matrix only uses 1 variable per axis — relative market share and market growth rate.</p>\n<p>The GE McKinsey Matrix (also known as the Nine-box matrix) has industry attractiveness on the y-axis and competitive strength on the x-axis.</p>\n<p>For industry attractiveness, factors to consider can be: Industry size; Long-run growth rate; Industry structure; Industry life cycle; Macro environment; and Market segmentation.</p>\n<p>For competitive strength, factors to consider can be: Profitability; Market share; Business growth; Brand equity; Level of differentiation; Firm resources; Efficiency and effectiveness of internal linkages; and Customer loyalty.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"how-do-you-build-your-matrix\">How do you build your Matrix?<a href=\"https://didierlopes.com/blog/target-market-analysis-with-the-help-of-llms#how-do-you-build-your-matrix\" class=\"hash-link\" aria-label=\"Direct link to How do you build your Matrix?\" title=\"Direct link to How do you build your Matrix?\">​</a></h2>\n<p>All the data will be hypothetical. The goal is to share the process and framework. Each company and market will have its own.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"1-define-your-factors\">1. Define your factors<a href=\"https://didierlopes.com/blog/target-market-analysis-with-the-help-of-llms#1-define-your-factors\" class=\"hash-link\" aria-label=\"Direct link to 1. Define your factors\" title=\"Direct link to 1. Define your factors\">​</a></h3>\n<p>When we talk about market attractiveness, from your company’s perspective, what makes a market attractive? Consider all those factors and list them. Try to list all the factors that have a weight in that equation, but try to keep them under 10; otherwise, it’s too many to have to assess, and at some point, their weight into the attractiveness is negligible.</p>\n<p>Now do the same for the factors that give your company a competitive advantage.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"2-weigh-each-factor\">2. Weigh each factor<a href=\"https://didierlopes.com/blog/target-market-analysis-with-the-help-of-llms#2-weigh-each-factor\" class=\"hash-link\" aria-label=\"Direct link to 2. Weigh each factor\" title=\"Direct link to 2. Weigh each factor\">​</a></h3>\n<p>Not all factors are created equal. Some factors will influence whether a market is attractive or not. Similarly, for your competitive advantage, what factors give your company a bigger edge?</p>\n<p>The goal is to select a weight for each factor so that the sum of the weights for all the factors adds up to 1. The outcome should look something like:</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2023-09-10-target-market-analysis-with-the-help-of-llms_3-4e10f18186b9f95eb641cfcd4cb9ac26.webp\" width=\"1400\" height=\"302\" class=\"img_ev3q\"></p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"3-categorize-each-factor\">3. Categorize each factor<a href=\"https://didierlopes.com/blog/target-market-analysis-with-the-help-of-llms#3-categorize-each-factor\" class=\"hash-link\" aria-label=\"Direct link to 3. Categorize each factor\" title=\"Direct link to 3. Categorize each factor\">​</a></h3>\n<p>Now you need to decide how granular you want your assessment to be. Initially, at OpenBB, we started with a scale of 1–3 where 1 is low, 2 is medium, and 3 is high. However, soon we found this to not be good enough since there was not enough granularity. Thus, we increased the range from 1 to 5.</p>\n<p>Once you decide on that range, you need to categorize it in a way that makes sense for each factor. This ensures that everyone on the team is on the same page when it comes to assessing a factor. For instance:</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2023-09-10-target-market-analysis-with-the-help-of-llms_4-56d2b1898c5f0ebbba68c2ad6f8b7cad.webp\" width=\"1400\" height=\"790\" class=\"img_ev3q\"></p>\n<p>This Google / Excel spreadsheet should look like:</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2023-09-10-target-market-analysis-with-the-help-of-llms_5-73cd1c076cdb06718b66cf077b4e0b58.webp\" width=\"1400\" height=\"896\" class=\"img_ev3q\"></p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"4-select-a-list-of-target-markets-you-want-to-evaluate\">4. Select a list of target markets you want to evaluate<a href=\"https://didierlopes.com/blog/target-market-analysis-with-the-help-of-llms#4-select-a-list-of-target-markets-you-want-to-evaluate\" class=\"hash-link\" aria-label=\"Direct link to 4. Select a list of target markets you want to evaluate\" title=\"Direct link to 4. Select a list of target markets you want to evaluate\">​</a></h3>\n<p>Create a new Google spreadsheet / Excel page for each of them. This will allow you to contain all details for each target market on the same page.</p>\n<p>For the purposes of this demonstration, we will use “TargetMarket1,” “TargetMarket2,” and “TargetMarket3.”</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"5-assess-a-target-market-based-on-selected-factors\">5. Assess a target market based on selected factors<a href=\"https://didierlopes.com/blog/target-market-analysis-with-the-help-of-llms#5-assess-a-target-market-based-on-selected-factors\" class=\"hash-link\" aria-label=\"Direct link to 5. Assess a target market based on selected factors\" title=\"Direct link to 5. Assess a target market based on selected factors\">​</a></h3>\n<p>Now that we have decided on all the factors associated with the target market attractiveness, as well as the competitive advantage, you need to assess each of these based on the target markets that you have selected.</p>\n<p>Each target market page should look something like this:</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2023-09-10-target-market-analysis-with-the-help-of-llms_6-0516ae1f2dd3da9fd311d202e4a39c47.webp\" width=\"1400\" height=\"972\" class=\"img_ev3q\"></p>\n<p>The factors and weights are automatically pulled from the “Framework page” built previously.</p>\n<p>Here you just need to set the rating from 1 to 5 (or according to the range you previously specified) based on the evaluation criteria defined. Each of these ratings is multiplied by the weight, and all of those values are summed up together. If your selected range is from 1 to 5, then it means that the minimum and maximum values are 1 and 5, since the weights add up to 1.</p>\n<p>Note that the last column allows you to add comments based on any additional information/criteria that you used to make a rating choice.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"6-discover-total-addressable-market\">6. Discover Total Addressable Market<a href=\"https://didierlopes.com/blog/target-market-analysis-with-the-help-of-llms#6-discover-total-addressable-market\" class=\"hash-link\" aria-label=\"Direct link to 6. Discover Total Addressable Market\" title=\"Direct link to 6. Discover Total Addressable Market\">​</a></h3>\n<p>On the spreadsheet above, you may have seen the total addressable market value. I will address how to find this value in a subsequent post.</p>\n<p>This is extremely important because even if the market is really attractive, its size can dictate whether to pursue it or not. Most of the time, you don’t want to be chasing a small market opportunity.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"7-final-matrix--chart\">7. Final matrix / chart<a href=\"https://didierlopes.com/blog/target-market-analysis-with-the-help-of-llms#7-final-matrix--chart\" class=\"hash-link\" aria-label=\"Direct link to 7. Final matrix / chart\" title=\"Direct link to 7. Final matrix / chart\">​</a></h3>\n<p>Once you have all this data, you can build the following for each of the target markets:</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2023-09-10-target-market-analysis-with-the-help-of-llms_7-e043544b5802b091b6d872287f60750b.webp\" width=\"1400\" height=\"1042\" class=\"img_ev3q\"></p>\n<p>Note that all you need from each target market is:</p>\n<p><strong>Competitive advantage</strong> — the sum of all the factors and their levels multiplied by their weights gives the x-axis.</p>\n<p><strong>Target market attractiveness</strong> — the sum of all the factors and their levels multiplied by their weights gives the y-axis.</p>\n<p><strong>Total Addressable Market (TAM)</strong> — gives the bubble size on the chart.</p>\n<p>Then you are ready to make a decision on which market you wish to pursue, and you have data to back it up.</p>\n<p>Note: There are a lot of assumptions, and you’ll never have it perfect. But with several iterations with your team, you’ll gain more confidence in those assumptions over time, ensuring that you are on the right track and pursuing the right opportunity.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"using-openai-to-bounce-ideas-to-assess-a-target-market\">Using OpenAI to bounce ideas to assess a target market<a href=\"https://didierlopes.com/blog/target-market-analysis-with-the-help-of-llms#using-openai-to-bounce-ideas-to-assess-a-target-market\" class=\"hash-link\" aria-label=\"Direct link to Using OpenAI to bounce ideas to assess a target market\" title=\"Direct link to Using OpenAI to bounce ideas to assess a target market\">​</a></h2>\n<p>Sometimes, it can be hard to provide a rating for each of the factors, or it would be better to bounce ideas off someone. This is where you can leverage OpenAI’s GPT-4 to help you get started.</p>\n<p>I built a script that would read from an Excel spreadsheet all the information from the framework page that we have set. That basically means:</p>\n<ul>\n<li>All the factors associated with target market attractiveness, and their levels of description</li>\n<li>All the factors associated with competitive advantage, and their levels of description</li>\n</ul>\n<p>Then I prompted GPT-4 to select a level for each of the factors of interest for both attractiveness and competitive advantage, based on what it knows about a specific target market.</p>\n<p>For example, let’s say we want to assess the competitive advantage for the target market “Hedge Funds” — this is what the prompt looks like:</p>\n<p>We want to assess our competitive advantage based in relation\nwith factors where we are have an advantage.</p>\n<p>Can you classify those for the following target market: 'Hedge Funds'</p>\n<p>The factors that we will access this market are presented below:</p>\n<p>When assessing Data Aggregation, these are the rules:\nWe attribute a value of 5 if We provide all data a market needs\nWe attribute a value of 4 if We provide most data a market needs\nWe attribute a value of 3 if We provide some data a market needs\nWe attribute a value of 2 if We provide very little data a market needs\nWe attribute a value of 1 if We provide no data a market needs</p>\n<p>When assessing Customization, these are the rules:\nWe attribute a value of 5 if Market will leverage our open source code\nWe attribute a value of 4 if Market will fully customize our platform to make it their own\nWe attribute a value of 3 if Market will customize a bit their platform\nWe attribute a value of 2 if Market will use platform as is and customize after some time\nWe attribute a value of 1 if Market will use platform as is</p>\n<p>When assessing Automation, these are the rules:\nWe attribute a value of 5 if Allows to save more than 70% of time\nWe attribute a value of 4 if Allows to save 50%-70% of time\nWe attribute a value of 3 if Allows to save 30%-50% of time\nWe attribute a value of 2 if Allows to save 15%-30% of time\nWe attribute a value of 1 if Doesn't save any time on automation</p>\n<p>When assessing Factor4, these are the rules:\nWe attribute a value of 5 if Very high\nWe attribute a value of 4 if High\nWe attribute a value of 3 if Medium\nWe attribute a value of 2 if Low\nWe attribute a value of 1 if Very low</p>\n<p>When assessing Factor5, these are the rules:\nWe attribute a value of 5 if Very high\nWe attribute a value of 4 if High\nWe attribute a value of 3 if Medium\nWe attribute a value of 2 if Low\nWe attribute a value of 1 if Very low</p>\n<p>Given this information, can you return a level for each of the factors\nthat is our competitive advantage from a viewpoint of Hedge Funds target market.</p>\n<p>Please return it in a json dictionary format with the factor and level only.\nDo not add any other text apart from that.\nIndent the json with 4 spaces.</p>\n<p>Then, using the following block of code, we can get OpenAI’s GPT-4 to provide its input:</p>\n<div class=\"language-python codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-python codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    response </span><span class=\"token operator\">=</span><span class=\"token plain\"> openai</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">ChatCompletion</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">create</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">      model</span><span class=\"token operator\">=</span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"gpt-4\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">      messages</span><span class=\"token operator\">=</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">[</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">            </span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">{</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">                </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"role\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"system\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> </span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">                 </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"content\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"> </span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">                    </span><span class=\"token triple-quoted-string string\" style=\"color:rgb(255, 121, 198)\">\"\"\"</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token triple-quoted-string string\" style=\"color:rgb(255, 121, 198)\">    You are an outstanding financial analyst and were given the task </span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token triple-quoted-string string\" style=\"color:rgb(255, 121, 198)\">    to perform market research on a possible market segment.</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token triple-quoted-string string\" style=\"color:rgb(255, 121, 198)\">    The company succces relies on your accuracy to categorize a </span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token triple-quoted-string string\" style=\"color:rgb(255, 121, 198)\">    segment and classify according to the factors and levels specified.</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token triple-quoted-string string\" style=\"color:rgb(255, 121, 198)\">                    \"\"\"</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">            </span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">}</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">            </span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">{</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">                </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"role\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"user\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> </span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">                 </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"content\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"> prompt</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">            </span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">}</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">        </span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">]</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    </span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">print</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token plain\">response</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">choices</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">[</span><span class=\"token number\">0</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">]</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">message</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">content</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><br></span></code></pre></div></div>\n<p>This is what the output looks like:</p>\n<div class=\"language-console codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-console codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    {</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">        \"Data Aggregation\": 3,</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">        \"Customization\": 4,</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">        \"Automation\": 5,</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">        \"Factor4\": 2,</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">        \"Factor5\": 3</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    }</span><br></span></code></pre></div></div>\n<p><strong>And that’s it for today.</strong></p>\n<p>All of this code is open source and available on my GitHub, here: <a href=\"https://github.com/DidierRLopes/target-market-analysis/tree/main\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/DidierRLopes/target-market-analysis/tree/main</a></p>\n<p>I hope you find this insightful, I appreciate any feedback as always.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/target-market-analysis-with-the-help-of-llms",
            "title": "Target Market Analysis with the help of LLMs",
            "summary": "This blog post provides a comprehensive guide on how to perform target market analysis for your company using LLMs. It includes a detailed explanation of the BCG Matrix and the GE McKinsey Matrix, and how these frameworks can be used to determine market attractiveness and competitive advantage.",
            "date_modified": "2023-09-10T00:00:00.000Z",
            "tags": [
                "target-market-analysis",
                "llms",
                "openbb",
                "bcg-matrix",
                "ge-mckinsey-matrix",
                "market-attractiveness",
                "competitive-advantage"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/openbb-2-year-anniversary",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2023-08-20-openbb-2-year-anniversary.webp\"></p>\n<br>\n<p>Two years of OpenBB: A look back at our achievements and growth in the world of open-source finance.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>Today is OpenBB 2 years anniversary of our incorporation. So it’s important to look back and understand the magnitude of what we achieved in 24 months.</p>\n<p>In that time we’ve had:</p>\n<ul>\n<li>100k+ downloads of our installer since we started tracking it</li>\n<li>2.5M bot commands have been run on Discord and Telegram from over 40k users</li>\n<li>GitHub project grew from 8k stars to 23k+, becoming #1 open source project in the topic of finance</li>\n<li>Our Discord group grew from 1k users to 13k+</li>\n<li>Our SDK has been pip installed over 25k times</li>\n<li>Our team grew from 3 to 19 around the globe</li>\n<li>For more, see <a href=\"http://openbb.co/open\" target=\"_blank\" rel=\"noopener noreferrer\">http://openbb.co/open</a></li>\n</ul>\n<p>But where were we 2 years ago?</p>\n<ul>\n<li>Only Gamestonk Terminal, the name OpenBB only appeared when we came out of stealth mode in March 2022</li>\n<li>No OpenBB Hub (only launched in May 2023)</li>\n<li>No OpenBB SDK (only launched in Dec 2022)</li>\n<li>No OpenBB Bot (only launched in July 2022)</li>\n<li>No Terminal Pro or Excel Add-In early alpha (development started in 2023)</li>\n<li>No SDK v4 which allows community and data providers to build their own data connectors, easily (to be announced soon)</li>\n<li>No community routines — our first feature aimed at community with upvoting and sharing of routines</li>\n<li>No open source PyWry — A web-view rendering library in python we open source in Feb 2023</li>\n<li>No OpenBB Champions — Our way to highlight users that do impressive work on top of our ecosystem</li>\n<li>No partnerships with universities, financial societies or investment clubs</li>\n<li>No partnerships with data vendors — now we have close relationships with most vendors you would know</li>\n</ul>\n<p>If we only focus on where Gamestonk Terminal was 2 years ago we had:</p>\n<ul>\n<li>Static charts using matplotlib (Interactive ones using PyWry was launched in May 2023)</li>\n<li>No way for users to run routines from other users from the terminal directly (launched 3 days ago)</li>\n<li>No AskOBB feature with LlamaIndex (launched in June 2023)</li>\n<li>No way for users to customise the terminal, select default data sources and set their API keys — all from the Hub</li>\n<li>No way to double click an installer and get started in a few minutes — hassle free</li>\n<li>The documentation on markdown files across the repository, today people often praise our documentation in conversations</li>\n<li>No AI features, no reports menu, no dashboards menu, no fixed income, no futures, …</li>\n<li>And the OpenBB Terminal charts looked like this</li>\n</ul>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2023-08-20-openbb-2-year-anniversary_1-b37a75ae976352f4a3a10ad483bfa0d3.webp\" width=\"1400\" height=\"1016\" class=\"img_ev3q\"></p>\n<p>Bill Gates said the famous saying:</p>\n<blockquote>\n<p>People overestimate what they can do in one year and underestimate what they can do in 10 years.</p>\n</blockquote>\n<br>\n<p>In fast-paced startups, I think a better sentence would be, “People overestimate what they can do in one week and underestimate what they can do in 1 year”.</p>\n<p>Looking forward to continue building the future of investment research, we’re just getting started.</p>\n<p>PS: On a personal level within those 2 years: I quit my full-time job to build OpenBB, got 2 dogs, got married and moved to the Bay Area. Life is great ❤️</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/openbb-2-year-anniversary",
            "title": "OpenBB 2 year anniversary",
            "summary": "Two years of OpenBB. A look back at our achievements and growth in the world of open-source finance.",
            "date_modified": "2023-08-20T00:00:00.000Z",
            "tags": [
                "openbb",
                "anniversary",
                "achievements",
                "growth",
                "finance"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/how-to-handle-equity-top-ups-at-a-seed-stage-startup",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2023-08-09-how-to-handle-equity-top-ups-at-a-seed-stage-startup.webp\"></p>\n<br>\n<p>In this post, we discuss how to handle equity top-ups at a seed stage startup, providing a step-by-step guide on the implementation process and including links to relevant spreadsheets.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>Previously, I shared how we handle equity at OpenBB in <a href=\"http://didierlopes.com/blog/how-to-handle-equity-at-a-seed-stage-startup-from-silicon-valley\" target=\"_blank\" rel=\"noopener noreferrer\">this post</a>.</p>\n<p>This blog post will continue that discussion and go over how we approach equity top-ups at OpenBB. It will provide a step-by-step guide on the implementation process and include links to relevant spreadsheets that you can use for your own startup.</p>\n<p>I will continue using the purely fictional example that I introduced in the previous blog post with John Doe.</p>\n<p>Let’s imagine that John Doe was indeed the right candidate for OpenBB, and on <strong>June 15, 2021</strong>, he was hired and accepted an offer with <strong>2000 options</strong> vesting over the next 4 years with a 1-year cliff. For simplicity, let’s assume that he will vest the 2000 shares by July 1, 2025 (ignoring the additional 2 weeks).</p>\n<p>This means that by the end of June 2022, John will have vested 542 shares (13 x 2000 / 48), and for every following month, he will vest 42 shares per month. Note that we only start showing the shares from June 2022 because before that, he was in his cliff period.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2023-08-09-how-to-handle-equity-top-ups-at-a-seed-stage-startup_1-009051891a60a0140e3af70451bb0a2a.webp\" width=\"1354\" height=\"200\" class=\"img_ev3q\"></p>\n<p>If you do this calculation, you’ll see that it adds up to 2022, whereas John was only granted 2000 shares. This is normal and is due to rounding, thus the shares associated with the last month are updated so that it matches the offer.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2023-08-09-how-to-handle-equity-top-ups-at-a-seed-stage-startup_2-75b7adaf8a055afad6ecb79c484d5f3c.webp\" width=\"1400\" height=\"154\" class=\"img_ev3q\"></p>\n<p>If any of the following situations arise:</p>\n<ol>\n<li>The initial assessment of the candidate was wrong, and they are not an IC but a Sr. IC.</li>\n<li>The employee has exceeded expectations, and their equity no longer reflects the value they bring to the company.</li>\n<li>The employee has other job offers, and you want to reinforce that they are an owner of the company and that their success is important.</li>\n<li>The employee’s vesting period is coming to an end, and they are considering leaving as they joined the company for the potential upside of an exit.</li>\n</ol>\n<p>One option you have is to increase cash compensation. However, offering equity (ownership) is often a better option, especially for startups with limited cash resources.</p>\n<p>In these situations, you need to consider an equity top-up. This means offering the employee a new equity grant on top of the shares they are currently vesting. There are multiple types of equity grants, but I will focus on the approach we use at <a href=\"https://openbb.co/\" target=\"_blank\" rel=\"noopener noreferrer\">OpenBB</a> and explain how you can implement it as well.</p>\n<p>First, determine how many additional shares you want to grant to the individual and, more importantly, how many shares would be fair for them to vest each month. The former helps determine their stake in the company, while the latter helps assess their value compared to other team members.</p>\n<p>In our case, let’s assume it’s February 2023, and John has been with the company for 20 months. We want to reward his contributions and bet on his future at the company, so we decide to grant him an additional 1,500 shares on top of his existing 2,000 shares.</p>\n<p>In theory, some companies start a new 4-year vesting period with a 1-year cliff for the second grant. However, the issue with that approach is that the employee will start vesting two grants simultaneously: 2000/48 + 1500/48 shares per month. Once the first grant is fully vested, they will vest a lower amount of shares per month: 1500/48. This means the employee would have less incentive to stay when only the second grant is being executed.</p>\n<p>To address this, we ensure that for the next 4 years from the vesting commencement date (VCD) of the second grant, the employee vests the same number of shares each month.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"how-can-we-do-that\">How can we do that?<a href=\"https://didierlopes.com/blog/how-to-handle-equity-top-ups-at-a-seed-stage-startup#how-can-we-do-that\" class=\"hash-link\" aria-label=\"Direct link to How can we do that?\" title=\"Direct link to How can we do that?\">​</a></h2>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"manual\">Manual<a href=\"https://didierlopes.com/blog/how-to-handle-equity-top-ups-at-a-seed-stage-startup#manual\" class=\"hash-link\" aria-label=\"Direct link to Manual\" title=\"Direct link to Manual\">​</a></h3>\n<p>Here is the information we have:</p>\n<ul>\n<li>1st option grant VCD: <strong>15 June 2021</strong></li>\n<li>1st option grant shares: <strong>2,000</strong></li>\n<li>1st option grant schedule: <strong>1/48 per month with 1 year cliff finishing on 30 June 2025</strong></li>\n</ul>\n<p>From here, we infer that in February 2023, John is vesting 42 shares per month and has already vested 542 shares (after the 1-year cliff) + 294 shares (7 x 42).</p>\n<p>Now, let’s discuss the decisions we need to make for the second option grant:</p>\n<ul>\n<li>2nd option grant VCD: We want to start it ASAP, to retain employee — for instance <strong>March 2023</strong></li>\n<li>2nd option grant shares: <strong>around 1,500</strong></li>\n<li>2nd option grant schedule: <strong>1/48 per month finishing on 30 March 2027</strong>. Note that we removed the cliff since we know the value the employee brings and that \"protection\"/\"retainer\" can be removed.</li>\n</ul>\n<p>By utilizing maths, we can create the following equation:</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2023-08-09-how-to-handle-equity-top-ups-at-a-seed-stage-startup_3-c5352d8e2a91b4f7dede7ab14cb91afe.webp\" width=\"871\" height=\"78\" class=\"img_ev3q\"></p>\n<p>By filling in the information that we know, we get:</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"data:image/webp;base64,UklGRg4YAABXRUJQVlA4IAIYAABwUwCdASp9AU0APjEUiUOiISESSH7wIAMEtIBsZlS3l3+V/i53+/0T8Zf3k9c/w74/+ifjz/Yf+5/jfgu/SekK/ofQv+HfUH6X/YP2J/v3/n/03wr/WvyK8wfiB+mfiJ+Ln2Bfiv8g/qX5M/3D9x+NXzb++f5P1AvTv5J/bv7b+yv9j/dT14P0j8WP32+Q/x/+f/0D8XP7N/7fwA/hH8X/tH9L/Yz+1//f6A/vX+M8X36x/lv9f7gH8Q/lf92/vH+O/wH+B/8fymfyv9u/xv+p/x3//94P5h/VP8f/ff21/uf///AP+MfyX+8/2j/Ff7v++f///tfc1/8/bv+0HsPfqX99Rk/QQNcKBEQAxuQ4a56+GBrdq97eV3PxZjrlHBfeJhTnfk4Qbp+z0A5soY52UJ14I8i2/81Mtnv7U4PE7Ml+SAM+Hfm7Hsku0UdqFmz931clCIqHdh4esSn1XRhrrPPJMZftOSDZz35LIq1YefqGqK0FXmf3biL6+IhTpkB5pOa8KqoCIoOUw00EE0hygLUJXkvI/sojuaqaVUv+7lrCL7NtJIyoCJWiodEwPPUBWgUDl963wBDHoFT+hKT/q2atCHeyalF/JFYY6BD3EaRZaaLG5alr3lGB8Yb/E9FEa0RtC3oVqaXIVdc1hOPmeFVS+70K/cYHF7Io8yMqRcbsS3ev+pyx+80p/Ji0ggjmN/oscu1W84TJ7Y9SpEaJiaep6bNKpAoqG2b/jBUcMMKWegYuZ+khhtPvocWd9LAufJDZiV+wAwRzzdewF/MsxDEzvOkqAd4zHHNjzCGzipd27piKcc4c9Q8rRfaMs/JCM7vsESbNF+awPdKYSILvuhOjKgcanxBgTwH9RfBLA5tRffDh6OzwNAFtiYCTsaTKe6gAAP7/iauY4OOr0NufLPg5GIyCGiBTJr0hPeaXfTtORakyx4kvle22ykEaD2M0OBS7EBmmmB9No69RNoJvq2qwl6Nf/RnM2t7ueWrwJlPTKQZKYnvRigp9Ji7R/t0Hw+gaquBEWrsf56yiDsFaFQKVSqmGUH8ZvWnHp7drXLsKJJltOH+raKFMKFpWl+8fw7R16u42mNwGoZ3bYZsI2fXYurjD/0IjZaZzoZnCtaLZTc2inJntEgJQmy3IFXWAMhU6AgHTY/HPbLPsnfEimnbphQn+2KujtXG8u285oMKAs6C6myyA0xeTKGaW5EL/EYFLOJEQoZuLS3wmZ+Of7Uf8OLU06kp9m97i/yMqHgpjLUJaFih5fvrZob6QoNF9ox9dT3kApum+b4VsfIlwmcz6sZ3UlgLzpFOQgh+aJjJhVZ6ocFaqzoaq/Uk8rOf1DsPdxcxOmQuaOafVShOElWiDHzkzPp6IAADsTVrBTVoPUCTinUc/I1+ICUHgdzBfhzH25NW/bv9JAGzWzsvjwkcxjRGvSONJaatOHu/y9LRRQ04U0nmyqFUYw1pwg8NPfNcrIG5nMswONpJwdYdMxvIMTs0l/jFOkMHY3+6/qSEgisqy8Hq8fFj6MKN65gylUnn2aVho7OgeZwlvTghkOqUedFMbl7XfY0HmejcBuSqEwh+LOb71QQKJ6JTuKIYw+XspCn5JZlSI3KVE3pYCxdfjBibRTvJ1f6yBmd/wa/dqRKg6/TWWEr4fdRZV1sexUJBMfR1+DQphVi0vwCzXdV1uTfUy9QJN96B+WdSBM2taw5tPC7qM3SlbqNa7NwUpoAbR2ZxUHwYaXzYhUGJ8kjPAbk/ubf5s5BtG+EcdRHOMDFf/2J8L+kOwzdFWboUnuWYm2kmJD1NvjMKot5be2Di+hKL6R+Vye43cPtcngPQMPcNiKjUwabHnrfLEl9qJCGKd2pRz9p2XSoic6d4qVs9tNH5pQC0952zIU0TysEzScQLtHoXOtOM/rGOqwa6p7j0LxJwHWKekwI8zyWI3d/lr6KK6C17buMf3BKEDJ4sJogBXNkG3VFuQMZcby+HVCdJsgP2VKJGzN/m8FKQmitBDHfxut0Hk6d8rRq62KV0Th6tG2LbJ+p2ZxKE0UkXCJvY2v3imV+q60pFFWvkrvQIb/R68euq+whai1mEOOS/0Y72SYlqnkoHrKCEZDyE1RmFuQuZ1T8gQwB5iLV2EEkg9UJXVBRbo33YNNN54ogpzLel7CAsEKzdGLV1PKih/NvbavlYIMfQzTB7gEG5SoVgyT2Rdwv0kTtwjK3Kbz8oAGFT3yBUStEUHsSujPgYgNWU/bx0L2HXLqGORTARx0jML04ZJaLX3kRLtgGh266MaoNJjGxPUpTi6Ro4F/uIpADjqzSgggXoxeOUeL/WObj9/J93DGPnqMhgZNMLy8C+s6b8ymfQ4FsBDkqG7Pw2tZUrXxtgvdSCcb85NlReAU2HemjZvl6rFmbZgTzZ5XusQ4YamCpBZFHHJfT5oYcTM8KYOWuzTUrkL+J3DAothQ/1rGV92v/Z9yAGH99tLvIoLklnJbe/UW1TU519pfET7+WAuFdcxagrqkoj38qt8G9JWevhfNgpJLtpapvaNDy79110+6dVHpPV5/E0ZZcy7F+0KlclvSD58TaK9LEgWkbWJGQJjv4UNf0AoMgjfc9f7IUaQ5U5awilZ6UulqhCaZdtHrDJmL6v3QwGH/BahufYWkyDTEVQP6SCS2nmmH/0ezfyQ9554DvnP3CqBaxwScjELMV+JNfKNIR2aY2OOctxzHAc+X+iDt5Brz5agjymedEGeejwnrrP2InWHdAWKOd1BZ8b7OX6qauL0BnuPqyGGLQCkYHnUz/Kk34yfGoFl2hPohdWK5kWCOt7a9rIFlEN3hCdQAKqjBLxrZBbPgvOHmKgdWAuVMav8UcfxnG6cD6M7D3hhlkqnwWuRh9TiXQLzyUn/qGJGbHH7/bMOMxEX+VEG40ojf6lFBqUPmekqyiS0nNtKTobkAG0mybEoN93EC+qQoft49NmJgCxo9Ypa/C9nLidQfwyFHpfQYYNmLYyJo+ez+t5LcVuwYFu9xeFdLrtZZCZKXleFp75Lw65ibTPgQ7rdFmH1mefKmFw5iYTNOD3GaK+FnCBuz9Y+fW4/iQeD/vb87blZfS6jtCKgYgvsNrVRDHXpmlTNwoRdI5gvVWoSjMlbpILR5I6H1zIs4a9qiE4vqpdn4ErRSFsLJ7itw/mzDBe4aSMNBro6Tv+KYtRUT8AZpwpi+p6tgEOd10wVRUUu0RCEto2kJHv4QNfX7TfMUXgAK4P6txZEzKBdq3uXs33NovywyMV3hC7aSqvCGSYlAfmWUm3EmecajuT/LNRo9zoOtIr3i0t3y1bMZeyUOCd1rjtd3oLjVGA5TfDEdbaKQoVSXV+JqyXve/a0d1t425i7sBD9mqzfxsbqf1btOXu1YELCn+CLkTwV0b95JDQ3kwQ8GUqycA3jmFhctq2LH9sZfVAy6OPg3dGSlCJfulZ8c/oZab//hirCgkFlgHKJjoCB9y/MxjwBidc+bWs/VoXncF1FAGB53450fco9LfOMbL5f6qyxtf7VpUm6dos5HJM1vnXl/13RMQM3f1LUamwUXLOJaIyzsOIxHthQweR5tc7NAOzcG3Owc005dwb4pbCvZ+gsXSfcoexRcC0UbZ5ZY2awJN1gfMv8KtliiyD5ylU4qGRsdOevRYkowtXCnz6la/SFrrScxHYhWN2XrDK6nxe1ErqhmUGEm3t6RggAFD9oRXPA0fCGztpLhPoi4IIKTgCUwEe/C9Qykt2zYkghNpVQLrkQcsE3mY0NOW/lHjLjEw+OK1prQz8sjrIRmE0vcPeCdQHLI35SVF8AwsWb40tfccNloHfvZQ9VQwXBlYtvTfOUrUVj4+ihkZjKLqgq2AEIwoFYAmQYHa7tE4bx64VRWK7zKVqlUI2uFN7kLVMWs/u6IuxRjSGe9KMCas1831gA2mEy8LvBhXhOJ3oT/XdGK8zOjf57A1OLFGUuHpDq9rSwx3o3xfvZzsvUbW5MG7QJk3NLa8+Zmkyik8obbra2l1+WlUe1SMyFml3dP5n0I3Yp6TDbEsisSabeFKbagWmWcpnQ7KU1N5YwJXkUnZYQoK6hqNBG0tYHiN5rP37Lwg+DWmkGcX9EzF7klrf21eKbJmLNHdI402zlTm93AOpfujI+JohVoafO2ZCdLkaQD/EFYoOAsTCBL7+BvH6KffSPPc2IZWG41V2ue6L1BfV4QSva39+stTX/UBpzMYbB1HEMyMGycKGe9exqVVEidyIIVh8SiUileHQKbJTKLzgBpj20busaEGVelecmT2htt2+e4QeQybpH/SqkjZuhQeWNzalfB+CPw1QUDlxrvZOUmNQnL5XkYdwV7oJIoqecj9WTYb7c+2b4bezT+NWN9PPZf3psI2UjaJmdlKiA8wUN8A6vSHj/+z5YzfS+rmXFPcWTkIjfEaFdEgxo+++iwbAVWOxLJO54f7SfaN+668L8up6spkmrHkVtnvftajT+wdRNFgpSEeQwlS+K3Y5SN+R/wKvmosUcq5u9/J1X90ouFd0f/DoxqUJ6LBfHkAgQyJBZmHFQ2OeYzZNQJy75+8HWT4t3aWZMeTJwAEChEF1rm7t/u7FBd9N0lhILqInpnR/5+n1dJ+IZSPt+Z97F/aXi2bKzE8Y/VufNoJPhlLmj8mRK2BRDV143/6bADhwc4bsm7aVhTi0VhckAzQuDpvko8TNAlsPRFfgHicqIkyUx5UKu5lsFUCpmb3HVjKpfPCZ8vfz/3dpF8HWN1qXpdvJrEB2stEfIw8l/Gv+vqtC+YT/nrhoRG8TdqLUvP7o4dmNA93JB6MA5RrP4/0r8B3Z2EcP55M2IryZ7S5kUMOci44kqzlBITkk+tMDeIerIf9dBZKgZSXYtbuiFmjYkSYB3sYTDGuVMJYu1tbO2XmOSS3twL/PrTJlkTZLGS+w279iVzfNam9P+CLLLpWmFZR5TeuGWNLBWyXc6+m9H2QR67S6bGeGsANtG5UXJL1Ts6LH7Uivtpj3AEytULXhQVYVviDczHdQgE6MWot/JCjkRVTzEHPSt0XViJQ/SaTCG9RI5NtfpiDix3KTgJKkD5suOuG11gvmili8Ar4QoIURr/O1vqf5lXs0EfbS8/1vcNt/441bNFOr1RqU1hmBW7CsIMA+b/4A4TqoQ0Rj5SLy7lehLruVB6AyQJFu9qioqYwB4ofgTh235+n3YdIp56ofSQtWRAbfrooJOgir/BJtNA+MGhlUZp0nEqLzkh0OxgIf22nyXVqIPQ6rE4BdYOUAmZ07/7aKwd3Prkx9MwT7A3WCBz55GrW3pJRXR6TzP7CMbYSUhO09WvCTjwDxINzIAF7mnRbY6UjR/9AoEKfNZoxVQiD9XypDStYuXTCNejEMxW5XvPsvHQevjItbozNM/IyBQ4yMtszMlSaI51rwN0zOmuKKdGqxwfbv3qFIeeLeMVGlufz9TQLc4MW9SKqppxLPXMFX3e7xvhW4Qx9OxXctOQXhDVDXGqagp6KmesbgEZL3noJuKBxQaqfG5zFsyTFhpStdyQGNeO60M37pOtM2w5ywDN/75/kIdpGBE00+QuGhpuVv367+5UnreeWVgo+SNwux6MOSt0ZkOocSa5tvCd0wZQbFH2xLgsLRxQIZwlaaB5mQyg+xx/P+O9FXrQ5wDeHA4e8sVYWcS87SQZ9olQJwPH4e69JRWQr1ONp7ncXPNOQYXXIYCKAf3NmKMivpNsS4K/1B50ITR7kXmmNzF96oCFEqGUMRZ8TW5A8KdR19EFe3EBEGU2TiQNyOjNQf6USVFYNgBgOqHSV75z3N5xU4E+dJ11Bw8V/vlMcvCVlIqykUiMXy6ingVxn2zXgAEpl17cTWAPQ2+cAm+Bh1P9IrIDunC3M0in8D+dxV6EankQO/tadPCa/E3Y8atnuw1ZlBvtseBplOfL54fOH1Y9sH+Jb6a4F4nEIV5Ji/taMtiQw0mmADqJ0u9b16iKUQkYYJ+ipSQWnYADUHrtvdVCvLvA4ScXY0S2aYRXibOYXRmCWPsreqVhGmrAavD4VS4rZDuna4jKx6TfBnp29vXHGgTzF9KsJq+kR+gV+kV7uYwZwX70HuT9IKsjAXI+rq2q7iNEZktdStwgcTWrzFhp3tsZUL929OKZXCsEVx/2xu2Y9QxLMqCJPeRf6Pczfm5fixlHSZ2AKztkpF0TB6MVHW7blwsIBVaOmWplB3WB3oTooP7whXXCIpGYBw0u2fnguNPJkvqTwmBdGGzyGX0JOJqMSLzFqi89d3mRzBIEBA80aCkwld71TYkvfHpey9K2IxMhcKba3q6Ps078iSXmHLmjn6CN1LZbBagA39bTysm6LynZrrtvgSMSgBtOsbix45RtnTi6ohwVQOB8ByOE/fh53u+HBfcNLZ6sdR2fahwH8JNpfrNew2b/DAapAuD3AthhlDiEsJDoid//DN7SwuLSYrkAFV6RJkB6YkXF7tRt3in+/+PiKhk91Ljtcdb+opUUURdOucJtBhYFkjEDm14gB5qJAfuoEP8oz56GnduzIIIAKBYzbFbFX5cLrOoXn72IlkcEduz3P31yX1JyH3MZqeRp2UbxX/n6OEKlPG1WGOsbnfVtfiRVklgMKcs5se5GkE4L2gAsS3cvvLusJ+wu0u0pIHPNXp9fNi4HVNi7bIGeIzIccITMPchLl9nnh2MY3kJLoc/yi2f+vdBVXoDTnJbzCDxm2rH/YaU5Uv8eY5W2XcYw78hHSWoTRiuWWZSrORPBMrY56ISNhjr0jSIurxkkKnin6M8BmLYgSmbHk38lkS2oWTDGe1GS/uS8dXT79YqaTa7dkdwC5viN80YniDALB7FFfAO72JeVGn4MDwW0iupQZKBAieAEGDUMFNmH7dodfPFNiQhwUTqjsmuR2t51adJNFbke3/BxdrSRcNYqYz2+j6qtMCVZgpPOTDVVRWcRWDGkF+KjfkqHJFKXJ/kHOu3oROp8MprOOG6fuov7W5BAY77d/j2wqE3wvxUshRT0ihyuX35MTXUSayHO33P7pAqKA7558DjOj0WW9C1c5YRNNKqMBgQdIoIe3fD/Dhh7dngAI3oV5igKjRHZHzz9LC6jCirpgr2moVayzpglFZkTZY1axtVvjjm7Lyfbry4RmzNJ2LJPhmFoDFFcOBAYkNwnLQKmdzX9RRoztfpOnCyRbZxEeZVTDqjg9avqoPZRnaLs+gUBvc57iqdVjdvvPvIq5QHWWGNGlaBk7slgDsJjlPqcw1Y2MOTX73xlgkqIpOC8n+ks4GBKfBpxOMXc9oLair0EWKXRByLU6LRuVpck+lvpeSA+amOVYUwSIHnVWEMLdCAgEOvS/woUy4Usof9pbhOqTiCxNJCCVFrKMH1dqNh9nDxaDiCqiZMQvh4lyLZcxxMPTN9lMgJtmZtgflNN0R2NOKT1wzC2/nzLF5dOQsQR9J0PCoTAJ3Oz6Kjb4JVvdRPwzjlPqcw1aouVTk8We9UbLJ+9RVS/JcHOoGPVjeAPvApSjIKQxc7zETCX3CrJHU59JFUU9aMUj8SdOlnqaJS8JfVJ/690S/5bkrAznDXLsyP96qTCJTk97+BPX0NCzMPrdkyp6dmIrHwHumNgA0BKxy9WVKuvjqd0IRdyqsZi6QKKQOH7Rq4ZW70Z1MAJozMsz8SHiDyQe8Cj+27CBy9r2xUX9zeSB555HQwPnZQzBy6dtQyrnHCbpIwihf52JYz8V7ggxDsfl3gYNxqE2dPkHtw7Bv21PqViTqsWBUaqbXYkwuwUpOMI5fBJ0aONb0JFCqXwx+1zbQN4WNa9pc1tjS5ll6Fj7lOJEdzZqKeMo1nJ/cNo3/LVBNvnLT1a4FFxlAStJjDNXd5a+XCkn/wu3xbGEnujWB2n6IMrR/5zfGvyIDPDNiJKZsEy1PQqKYiqb53WCvIoWDyf9xnavjYyLJUbWxHscu9Oj1Npczh1iwFndRRVQQrmIHlxUYUF2HKPbXauRIPp+ina1wrpXVOCBSX6luBubtLKd2V2t/FUpTvFw+9xrNVPbTIOD60n2JPrWiM+U9xROOLIdjPhE6fy5UpqQUIIEJdHHy5iPQvEzH8dpzELdZEo3H22kifsNcshLD543knRXcLOFKF3Gyxn1fQ/IgZh4RlaxU1XgZSYV4cbk3Lp6CR+Usoux74nGW4dAePEdIHVCovve5rnLFL9gAAAA==\" width=\"381\" height=\"77\" class=\"img_ev3q\"></p>\n<p>And thus we know that we can get the value that makes this happen.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"data:image/webp;base64,UklGRrYPAABXRUJQVlA4IKoPAAAQPgCdASpIATcAPjEWiUOiISES6q3MIAMEtKI8SOFTt/l/+l+Ab8l/nv4p/uJ6s/hHxL9C/ID+sf+Le6f0n0H/hv1H+t/2P9hvyr+Cf5n+AHm/7U/zv8c/gC/Ev5V/UvyJ/qH7hcYVh/9c/xH5d/AF6ZfJv7N+Yn9j84n9O/Ij3A/Ef6N/YPyZ+gD+Gfxr+w/2D9kf7V/9/oD+3eBh9X/vn+q/pv4AfYB/Ev5j/cP8D/cP8L/pf/n8fH83/e/8F/xP7z///df+T/1D/Mf3n/D/8H/I///8Av4t/Jf7l/af85/v/77///+n94Hry/Yj2HP1C++stzV99v8FgZqZMslLgVhwxOct4LxOUSRnXUAjE5/5Qj0s2v+mCGPcFap4XbAXOnej7GKJV3YbPVLsifGXTwaCyn4+s6l7MgNrn5Dwbh38BCj5R6+g8RFHy+TvHWb/CR5NpHpU39/n0AaaIBRBkj2rQV6dHsLKAR1F6uKzPoHgOhkLuSY09ohQRrncEIsKFuX2UfAALYkql4+CE+bZCsoYNwfp66BP6ZQff4aw1VKGQ0jOwS5m0WVoZRukcT5GxfZJyUDUemGNZbixs1T9uaaAOOyZI0OGLQRDaeMfkqvvm6uxW9KR+0kIqDAof8reWaLlDHNRsDObcEmgnXkTlOtTP65p0TkAAP7/4mlkAXk2zGH34eSrLoae4+8At/BG6EfzA63LZsYHBIbe9EzgS32qmJBF7pLZbz3srwHlZGfAwCqJZF8aPvSTuym3iOlhJ+RiHuCGND6pe40faUggmd8av2paua1FKzoB+c3qHTWYyJ7zKCu5OnCqc7z4GP0AhheWhrd4dUEfyiMTw8og3kEreon+ubtl5IUg8IeGRzLiYK7eypmQkUi1sbUSzqKE4IVOzYrr6Xp58XtTLAq4VgSsaThKDkrxCQQpO5JjIf14mHlac05RT35WbSHh+0khnDGNQABl+4nyZe4Gxr0rspFN7GAGLgkMi0PGXRt5EiiU0/NSlAE/g93HfMCYFoDgNwn5UxAuohHcQOa8ahB5sAwo+Od8yhqXZfx+SIt8ub56fgb1FqY9TokAL8uAsjegfVPL+/2axRQOoJ53ofUq9vrXFA4xtz+Km506d4eHP9rjK68I1qlKeDmW+ydHM71CKT+pVrr/41q0XnucMi2cOqug/AX9wuzbyVbkNnEqmmkZk/YB3t+ZUwf2jX/b/t9algLCyFQjSGNT1U+s5IXRsN6yNjvhPCHxDuYsnLbhIM55Ip5joVs3Q+/FAfQtWXR0ztBdPoDEQYfSH7v7P/+kSOYzHtsORQwZY/qybuvCokjQ8dCE7JrChBIJ80WeqODxTs7blkk9VnaaqjtH2hDUixHzAio7hXqofz23uT2XWOY5ZLrLDOCJGU+z62wNZwmQSXQP0gWm0Sd+ljFSQpHs/PKVbuSaFZ8mFxiSA9QP9ucRwjSD8A6y8oQfeOskOUaTg4caR6nZEnMdblyveeg155ZSjoDqclJfSsBxvGCS77rsjD82ZwvCjAvOfur0AXGPJUwwpmY+rN6wxWVOIH0osGZHaPRtogshEyLU8/jR4SQY0x3xbHu9Y1gxylbIEZYQB8dys6LIwWNk6jbcgHFtGhltieiuWwAD2zOoZD9gMHDTMlQ4MJisPZl5JwLm5b9nkPDfIor8rYMY9lPU3jHr9PCs5xrWlNFTvKsdS62bDPnAKhFiWquKYlz+P8FbT7rdoNbBo6RagDa+eKIaVEQdHVCRtxagCw4XaFOvh1lQslqj/Cc1NgSFfD0jS+5ddWhpUvaoxohjndWeXNdRF17+ufAk8qIwJ1IUGv1mGYcAZJd10UmGy2XielMPaMgP0f7jzLHXHgzFN/tE+8Uu5hCPN+QSMlpfA1P7s4V0Gq6ehrlwOGMwHNGBo/sFIg2sWyqC2i9y/jbiL7+8KMmjN3bAShoLpTtyCIAEK7bXeqm+mMbz8B5YiYWLZpjl3LPES1cM/sKX0D9f2KNqQE0VrHCXRa/y/Nfi0AfY4hlXg/oQOePJANgEfJTIIomlwNfhB7aPnYUYPK/7eTZj3s5Z6Co+0mZT0OWB1hr+rSQRmDlkHn1YV5rZzBT+cmzHKqT9wjhegDIKxWPWCzoDfp6/mghXpdpxkOblQoRiPjltENArqXhYKEG0cncgPPr8N4cUMQ7jGLvdwHD3yQmG8Bko74+ujr0c2h6OwqyQZiY5/pYRqGRgRMVT+SpvNbFty+QeuEsejgnHKJZ1aggXKvEcpBDpVWAlI048+mxaQLsuEIWs72Pa6A/rX/2n3jGXDSyqu+BfV/qnXXUtjtm4wz6wJMAxhaUm+kqFTpWJG6DVnQ1S4vYlZTay3NNbdK8tuvt/YPSzAUfo70IsjC2+rIg26A7Yt8O23p+QNyPF0+C/dmSsieb+agtjOMvUxTfaJ7tq+2QfdG58xsOFE2ovFbqb4o9IkhJZxWr0LVuBb6ebLLavoSya+JgS03PXrFy4i0O0Cg6dM5Hz/7HcfPjucaf0ajg5owqdxb0Wu7LkfL6mf8JFRNCZ/JfIXl/LYiKPYIlL7IyXWjwt4ZsEKb0fM/t0Bvdl+BCzlgFBMzG/+LxqvlElQ//wuSnjmt+t0epLJP3ry7YYjymndkl33sDbjORP3kgsB7wQ30kgckBADuTi+MQIQMthRzvFcaO1n4ajhleEKTfXb6UEiAu40O/ekiEXaNepHN4jhS598rUxqHEdv+jIcE8AHOS9CCWqqXqLidodu355YBNOGqgO1JqRaHUw8s6FfC3X6FnNyyI2aYcl/JBm40mAlcKNybm+ZrwmuX8Drd4IMih6/YIXNNez9iTzlv3BqAJSnfuG/NoH1XQ2Fw+JkqKs+W7roEfXGgkgQB2LZDCSoPrB8S25R7Ws+vsjBvOlace4Q2GQR1fu+d3Pg7GKvrrIcHAGe4f+AnqqxjbUW7z54hZloM6bC5hAn7tZ1SL97+TG4VSs0O9SbJBDG9dt4njV7ba5FGoV1OkjsXSWQ2wliMLDDTegyxLFVCKJKcNJPcwWf0oKBWac5PkW+EfbNPiwdTvTBzilSDJDcY4xZl9doneq64DyZ8NO3acz52rgy+Vr2oR4Wo56Os4a50EK+dEYsgq/DKgAo9/7oyDy/6HO6XinCryw6wHv5UpJC5zHUB1rGaExko3n2ti+WiT2Ypg5FIV8yb0jPO9p6Ue98f+Hxfw0/jyyVYYHxE0VU40vAeZlsqyZpYD1BQ0MMT8EO48DjDwlTFOmI3TCoEwA4pJfIpbZuaPNDbRYeqAXKy0j9qwf7dGPQ4S6S5XB6EAjq2r176iES5gvLbKty8lqwiHuci+iVilu0jI2A22DXKvdhHE8w8WJhNfMdXPR/POzaEgLyPixveO4WFVZqFISzChHK32bAIlSwbgFgLfeg1VUE5SFgiOAj9dF6D5bKdOdszq5g/1ORJVbwG3QRaQRPiSmDQ/jDy4NZEcklvjQ6IXwY5T0jVugjQFkISZYC6BUsbA6flQ5WrzqyWZ2WJWqJz+4mRCkWDnbo7agqJVXytZdCi8CwXb+7bgCgcexyZKS+lLS24ZJKR1xoH2w0hp3UV9azFGSqUXj47k39j+F//9GHmklzjMgZjXR0wKDRUwrcb8pbauesD336mciTEYK8o7jFWVHkF0ehJH8JgFq9J9j+o1MuA43K2OASusaASjJAFvRT6UDe/wc4+OYeoSAN3pJLBhuGgI4QA0KYZuSz6+TUz08HniMqIIWuh5ApBZuF/0yv//AU8IpeXAQMN/TcXu6W6PaX4kj1kEvK2x30EI4P4ycHv8tBYM6nWgZRsOi3597015Nd/o7MiUevSIUpuu/d9l6LXOe89viqIVCadLBQ1QVU4w4ZpxPmzI33F2j1z6J/pC26exA3YEPiw09EAzjrlwjp6Y1mYi7HOGOldz4bkSBaHEE9wQ0qkS9BISMe1srqvo+DI3if8KJ1JPyGm1LaoDfsnPe4WPElMlSZlD+7dZMGEhx0K/4YLJXE3QJ9vDKwxrDbMUpYatUwRwUQVA0AATlk/Ee+8uRuTF644RiIT+jLgmeTCUXTrpgteI/nR8ZAJGqsAx2m6jASb8WM3NmsK8stCU2wUk99LIIVy45xmB/skXaN6yI6lKFtb544kUizpBRkrAFiggsbmEFyEWRlJGHoHybVGwOifHRfFDnq3H+zTwJO6u/cXjkhATPb4XAUkIeQILuNyga9d8pad1Ze8sN4yoX3AhNuv8m4XBU2RR8ymKz5Xw360nQfhktNdK7rXsz8uro26TxWChRz/DUbOS7Aku/92lkBicu03ElL8wKvb60cTt9N6PWEzJ/Pyl4czQZfllcOx8+JUYvs9Ug3GHh99QqWppu2oT/9tA3LFPmqf116ATlt8+uaUY5cYegtmGxT5U2TEE+olN7RWb1rsQvuPjxz+FheHKHy48s4PN6W5L1+S+6Qtj6/WGAOEzeREzbeYXZ0Wi35mDgrpj4LcEM0z6Cb7/szC5sxx2XFEf67g/kwX93usRkH0GiWLeb3khp1Joiy1dy9giXkxdK2E5TziN9AmyR0WAjVx/F4mK8pxXK0wE/jTtPvW2mE7ADerrlDO8osMGjAlM7VJc64yoDtDHyhQcSZMmYjq2REyyO3iO3oZUTAR7jAqsegDOgH6XBEN2XYgyKsTM4Ki+hjVA8mktpEKjsbEpiJa3i5bK1QZdZvHHk6MeNbuzqFGVqrHxTDih4r4qWpleDCAiLlG8siTQ7f/Ln9MSb8DsaxeWYPzBzwafwzGoCLLD1IVKcTxWOjTjVVkRgYOoewZP1idztvgBFoKH2GxzRzgfWwrfBVdmNlxp2Fl9x8eOavCV33hu6UWmi+4quuVJ979/XLENrRsqtdYv2fX+MYUL9wJW6cqWeq4Woxu9iE5PqOlTdSIOLgVHJkmcWNJ6deBbAM1W3OHxvjajx6nUmff8cNqPh/BZMpo2cnhbJEcHLCQUGiAVFfwrfnEYkMmAn8adp9620wojBLyYu338cwUlPnBJ2OsMdRVp54eh8oUBcqiED5cmYeHWqTlmvE7QO/fdfgXX37woJGG2C8x+mmTU7x2eaA6qePXJf/390Rueu2VAyXQjxlxHuLH5pt+W3GEeSw/oytVY+dTYKRqcPuhDAtKHkPgO+h6Tz8aBXPWbvvbYCKhI6Tii2DpMj81JNYmqbsKsZK4M1AuSxb+PRgNQg9FjR/8BKeQmijcxpwE4JFqzyIwLl0K+VPDKbhAc0btbhcKkgvYm/CrKrmQ+PBoDUarn6Dj4Lho5eVAB3k+GOLDYWCteiJ8LjLAHM80XYmIqnM0XRwgyXYyATFG4zAKoQgkuY8LQ8AAAAAA==\" width=\"328\" height=\"55\" class=\"img_ev3q\"></p>\n<p>However, we don’t want to give the employee fractional shares each month, so we select a round number around the one that makes him receive around 1,500 additional shares over the course of 4 years.</p>\n<p>In this case, that number could be 55. This means that the top-up number would be 13 (55–42), except on the last month of vesting for the 1st grant where we need the adjustment.</p>\n<p>When we multiply 55 shares per month for the next 48 months starting in March 2023, that adds up to <strong>2,640</strong>.</p>\n<p>However, the employee was awarded <strong>1,500 shares</strong> (2nd grant) and still has 27 months (from March 2023 to May 2025) to vest 1st grant shares, which corresponds to a total of <strong>1,122 shares</strong> (42 * 26 + 30, remembering the adjustment done for the last month). This total would be <strong>2,622</strong>, which obviously is different from the expected 2,640.</p>\n<p>Therefore, we update the value of the number of shares given on the 2nd grant so that John receives 55 shares per month. In this case, for that to happen, the 2nd grant has to have a value of 1,573.</p>\n<p>But obviously, you don’t need to pick up your calculator every time you do this. I mean, what kind of engineer would I be if I didn’t somehow automate this?</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"automated\">Automated<a href=\"https://didierlopes.com/blog/how-to-handle-equity-top-ups-at-a-seed-stage-startup#automated\" class=\"hash-link\" aria-label=\"Direct link to Automated\" title=\"Direct link to Automated\">​</a></h3>\n<p>The spreadsheet below demonstrates what an employee vesting schedule looks like, and below I will write a step-by-step guide so you can fully customize it to your needs.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2023-08-09-how-to-handle-equity-top-ups-at-a-seed-stage-startup_6-417a74fea9c3d1658083f9655096d072.webp\" width=\"1400\" height=\"950\" class=\"img_ev3q\"></p>\n<ul>\n<li>As a result, <strong>E5</strong> will be updated with 11 months afterward to represent the month before the cliff terminates, which consequently leads to the following months being displayed in <strong>column E</strong>.</li>\n</ul>\n<ol start=\"2\">\n<li>Fill in the 1st grant shares in <strong>B5</strong></li>\n</ol>\n<ul>\n<li>As a result, <strong>G6</strong> is updated with the total shares from the 1st grants vested after the 1st year. The following rows in <strong>column G</strong> are automatically updated until the vesting schedule terminates.</li>\n</ul>\n<ol start=\"3\">\n<li>\n<p>Adjust <strong>G41</strong> so that the sum of shares in <strong>column G</strong> match the shares from the 1st grant in <strong>B5</strong>.</p>\n</li>\n<li>\n<p>Fill in the top up grant vesting commencement date (VCD) in <strong>C6</strong></p>\n</li>\n</ol>\n<ul>\n<li>\n<p>As a result, <strong>column H</strong> will automatically get populated based on the value that, when added with the cells in <strong>column G</strong>, returns the value in cell <strong>B19</strong>.</p>\n</li>\n<li>\n<p>This will also allow us to compute the months that have already been vested from the initial shares in <strong>B11</strong> and consequently calculate the overlap between shares coming from the 1st and 2nd grant in <strong>B12</strong>.</p>\n</li>\n</ul>\n<ol start=\"5\">\n<li>Fill in the top-up grant shares that you are thinking about offering to the employee in <strong>B6</strong>.</li>\n</ol>\n<ul>\n<li>As a result, the same computations that were explained earlier in theory will occur. This will result in a recommendation for the top-up shares in <strong>B15</strong> and consequently the amount of shares that the employee will vest monthly in <strong>B16</strong> so that the amount of top-up grant shares is met.</li>\n</ul>\n<ol start=\"6\">\n<li>It is very likely that the number in <strong>B16</strong> will not be rounded. Hence, we fill <strong>B19</strong> with a rounded version of that number.</li>\n</ol>\n<ul>\n<li>As a result, <strong>column H</strong> will be updated so that the total shares (from both grants) in <strong>column F</strong> matches the selected value in <strong>B19</strong>.</li>\n</ul>\n<p>When looking at the total top-up shares in <strong>H67</strong>, that value will no longer match the total top-up shares that we wanted to grant to the employee and that we decided at the beginning in <strong>B6</strong>. This is because we rounded the value and thus impacted the number of shares necessary to achieve that.</p>\n<p>The amount of shares needed to update the recommendation in <strong>B16</strong> to the rounded version in <strong>B19</strong> is displayed as an \"error\" in <strong>B21</strong>.</p>\n<ol start=\"7\">\n<li>In order to fix that, we simply need to update B6 with the sum of B6 and the error value from B21.</li>\n</ol>\n<ul>\n<li>As a result of this, all the values should now match, and the combined total amount of shares given to the employee in <strong>B8</strong> should match the sum of the shares spread across dates in <strong>F67</strong>. Plus, the error should now be null in cell <strong>B21</strong>.</li>\n</ul>\n<p>And that’s it.</p>\n<p>I hope you found this useful and are able to use it internally to share with your employees so they understand how the top-ups happen at your startup.</p>\n<p>If you want access to this Excel template, feel free to reach out to me on Twitter or LinkedIn.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/how-to-handle-equity-top-ups-at-a-seed-stage-startup",
            "title": "How to handle equity top-ups at a seed stage startup",
            "summary": "In this post, we discuss how to handle equity top-ups at a seed stage startup, providing a step-by-step guide on the implementation process and including links to relevant spreadsheets.",
            "date_modified": "2023-08-09T00:00:00.000Z",
            "tags": [
                "startups",
                "seed-stage",
                "equity",
                "compensation",
                "employee-retention",
                "vesting",
                "management",
                "human-resources"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/how-to-handle-equity-at-a-seed-stage-startup-from-silicon-valley",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2023-08-03-how-to-handle-equity-at-a-seed-stage-startup-from-silicon-valley.webp\"></p>\n<br>\n<p>A step-by-step guide on how to handle equity at a seed-stage startup, using a fictional example from OpenBB.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>As a startup founder and CEO, you need to wear multiple hats, from engineering and product to design, marketing, and even finance.</p>\n<p>Today, I’m going through the details of how we handle equity at OpenBB. This blog post provides a step-by-step guide on the implementation process, including links to relevant spreadsheets that you can reuse for your startup.</p>\n<p>To make this post easier to follow, I will create a purely fictional example.</p>\n<p>John Doe, a software engineer from Portugal, has been contributing to the <a href=\"https://github.com/OpenBB-finance/OpenBBTerminal\" target=\"_blank\" rel=\"noopener noreferrer\">open source OpenBB Terminal</a> for a few consecutive weeks. He not only fixes bugs but also adds features that the community has requested through pull requests and on Discord. Additionally, he is a fast learner and gets along well with the current team. This sparks the interest of the OpenBB team because having this open-source contributor work with us full-time would be great, rather than being limited by his current full-time job.</p>\n<p>From here, we set up an initial exploratory call to better understand John Doe as an individual — what he is passionate about, why he has contributed to the project, and more. We follow up the call with an interview involving engineers to assess his skills and experience. Finally, he joins a call with me, where I sell the vision of the company and explain why what OpenBB is doing matters. At this point, we extend him an offer. Up until this stage, the recruiting process is standard, except for the fact that we have a “filtered” candidate coming from the open-source community.</p>\n<p>However, as a startup, that offer cannot (or at least should not) consist solely of cash compensation. A startup <a href=\"http://www.paulgraham.com/growth.html\" target=\"_blank\" rel=\"noopener noreferrer\">operates at a much faster pace</a> and is riskier than a company. Therefore, in exchange for hard work and long hours, you should offer part of the company through equity, allowing the employee to benefit from the upside in case the company achieves a successful exit (IPO or sale).</p>\n<p>So, how do we decide on the equity to offer the new hire?</p>\n<p>It’s easy. You follow your company Option Guidelines.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"option-guidelines\">Option Guidelines<a href=\"https://didierlopes.com/blog/how-to-handle-equity-at-a-seed-stage-startup-from-silicon-valley#option-guidelines\" class=\"hash-link\" aria-label=\"Direct link to Option Guidelines\" title=\"Direct link to Option Guidelines\">​</a></h2>\n<p>The Option Guidelines are an Excel spreadsheet approved by the board. In this document, you explicitly create <strong>bands (minimum and maximum range options)</strong> based on the role and stage of the company. Board approval is crucial as it allows you to extend the offer directly without needing permission from the board since the guidelines have already been approved.</p>\n<p>Here’s what the document looks like:</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2023-08-03-how-to-handle-equity-at-a-seed-stage-startup-from-silicon-valley_1-76c61eeb7e4b6b35938436102a0d9d1b.webp\" width=\"1400\" height=\"1033\" class=\"img_ev3q\">\nThe total number of shares is random and not representative of OpenBB.</p>\n<p>First, you need to ask yourself what roles your company envisions needing. Within those roles, there are two things to consider:</p>\n<ul>\n<li>\n<p><strong>Departments:</strong> You may differentiate between Engineering, Marketing, Operations, Sales, Finance, and HR/Admin. You can also add others such as Design, Product, etc. Note that having different departments does not necessarily mean you need different band structures.</p>\n</li>\n<li>\n<p><strong>Titles:</strong> You’ll want to be able to “compare” individuals based on their contributions. For instance, Vice President, Director, Manager, Senior Individual Contributor, and Individual Contributor. Note that if you have fewer titles, the bands should be wider to differentiate individuals with the same title. If you add five levels of Individual Contributors, you’ll want narrower bands.</p>\n<p>I recommend starting with fewer titles, KISS: keep it simple stupid. Again, having different levels does not necessarily mean the bands need to be mutually exclusive. A Manager does not necessarily have a higher band than a Senior Individual Contributor; this depends on your own company culture.</p>\n</li>\n</ul>\n<p>Next, you need to differentiate between <strong>company stages</strong>. This allows you to distinguish employees who join very early when the startup carries the most risk. We distinguish between three stages: Pre-production revenue, Pre-profit with production revenue, and Profitable.</p>\n<p>Once all these categories are completed, you should have a similar table to the one shared above. Now, it’s important to fill in the equity percentage. For privacy reasons, I will not provide the specific values for OpenBB but will create a random example.</p>\n<p>Let’s imagine that OpenBB Charter has a total of 1 million shares (assuming only one class of stock for simplicity). If our priced round values the company at $10 million, this means that each share is valued at $10.</p>\n<p>On the top left of the document, we will insert the number of shares, which is 1,000,000. Then, we adjust the % LOW and % HIGH columns, representing the range of company ownership we want to grant to this individual.</p>\n<p>Let’s go through a fake example for the SW role:</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2023-08-03-how-to-handle-equity-at-a-seed-stage-startup-from-silicon-valley_2-c808080891bf097da88735a6f87e2180.webp\" width=\"1400\" height=\"123\" class=\"img_ev3q\"></p>\n<p>The column “Low Shrs” is computed by multiplying the % LOW by the total number of shares. On the other hand, the column “High Shrs” is computed by multiplying the % HIGH by the total number of shares. This value is important as it represents the amount stipulated in the contract.</p>\n<p>Let’s consider a scenario where the company is in the Pre-Profit stage with Production Revenue, and we want to hire an Engineering IC. Based on our assessment of their skillset and fairness in comparison to other team members, we would offer a contract that vests over time between 1000 and 2000 shares.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2023-08-03-how-to-handle-equity-at-a-seed-stage-startup-from-silicon-valley_3-2ae84e2c30bc228ab07d0090245b6ba2.webp\" width=\"1400\" height=\"121\" class=\"img_ev3q\"></p>\n<p>Next, you need to decide on the vesting calendar that the company supports. The most common option is a 4-year vesting schedule with a 1-year cliff. This means that while you begin vesting during your first year, you need to stay with the company for the entire year to be able to exercise those options. The 1-year cliff protects the company from employees leaving early or underperforming.</p>\n<p>Carta provides a good explanation on how stock options work <a href=\"https://carta.com/blog/equity-101-stock-option-basics/\" target=\"_blank\" rel=\"noopener noreferrer\">here</a> — which I recommend to everyone.</p>\n<p>Please note that in theory, while the value of these options is $10 per share, the startup will need to conduct a 409a valuation to determine the fair market value of each option, which is likely to be much lower than the initial price, such as $1 per share. And this is the strike price that employees will need to pay to exercise the shares.</p>\n<p>Note: when selecting the number of shares, use a number that is divisible by the number of months that the employee is vesting, e.g., for a 4-year vesting period that would be 48 (4 x 12), which ensures that employees get the same amount of shares each month, and there’s no need to account for floating numbers.</p>\n<p>This is it for today.</p>\n<p>In Part II, I will talk about how you can handle equity top-ups.</p>\n<p>So follow me if you want to learn more about what that process may look like.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/how-to-handle-equity-at-a-seed-stage-startup-from-silicon-valley",
            "title": "How to handle equity at a seed-stage startup from Silicon Valley",
            "summary": "A step-by-step guide on how to handle equity at a seed-stage startup, using a fictional example from OpenBB.",
            "date_modified": "2023-08-03T00:00:00.000Z",
            "tags": [
                "startup",
                "equity",
                "silicon-valley",
                "seed-stage",
                "openbb"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/keep-track-of-your-startup-metrics-using-a-custom-ios-widget",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2023-07-29-keep-track-of-your-startup-metrics-using-a-custom-ios-widget.webp\"></p>\n<br>\n<p>Keep track of your startup metrics using a custom iOS widget. This blog post will guide you on how to build a custom iOS widget that displays your startup metrics at all times. The entire code is open source and requires minimal coding skills.</p>\n<p>The open source code is available <a href=\"https://github.com/DidierRLopes/opensource-scriptable-widget/tree/main\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>If you have a high level role in your organization, you are likely obsessed over a few metrics that act as the north star for your company. Whether that is MRR, number of customers, GitHub stars, AUM, .. depends on the type and stage of company, and what you are optimizing for.</p>\n<p>At <a href=\"https://openbb.co/\" target=\"_blank\" rel=\"noopener noreferrer\">OpenBB</a> we are currently optimizing for <a href=\"https://my.openbb.co/\" target=\"_blank\" rel=\"noopener noreferrer\">OpenBB Hub</a> users, since this is the place where you have access to our entire suite of products. From <a href=\"https://my.openbb.co/app/terminal\" target=\"_blank\" rel=\"noopener noreferrer\">OpenBB Terminal</a>, <a href=\"https://my.openbb.co/app/sdk\" target=\"_blank\" rel=\"noopener noreferrer\">OpenBB SDK</a>, <a href=\"https://my.openbb.co/app/bot\" target=\"_blank\" rel=\"noopener noreferrer\">OpenBB Bot</a> and soon — the highly awaited <a href=\"https://my.openbb.co/app/pro\" target=\"_blank\" rel=\"noopener noreferrer\">OpenBB Terminal Pro</a>.</p>\n<p>So everyday I spent some time checking our startup <a href=\"https://openbb.co/open\" target=\"_blank\" rel=\"noopener noreferrer\">/open page</a>. However, whenever I had to check these on mobile I had to open up the browser, type the link and then look for the metric of interest.</p>\n<p>Hence, to save time, I built a custom iOS widget that displays these metrics of interest at all times. All I need to do is unlock my phone and <em>BAM</em>, they are right there.</p>\n<p>So, today, I’ll teach you how you can do the same with minimal coding skills required. I open source the entire code, so that you can get up to speed as fast as possible here: <a href=\"https://github.com/DidierRLopes/opensource-scriptable-widget\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/DidierRLopes/opensource-scriptable-widget</a></p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"track-your-open-source-metrics\">Track your open source metrics<a href=\"https://didierlopes.com/blog/keep-track-of-your-startup-metrics-using-a-custom-ios-widget#track-your-open-source-metrics\" class=\"hash-link\" aria-label=\"Direct link to Track your open source metrics\" title=\"Direct link to Track your open source metrics\">​</a></h2>\n<p>This section will provide a plug-and-play example for your open source repository.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2023-07-29-keep-track-of-your-startup-metrics-using-a-custom-ios-widget_1-52b9ef472cb7c06bb61fb99d0e1f4c89.webp\" width=\"636\" height=\"316\" class=\"img_ev3q\"></p>\n<p>These are the steps necessary to have it working on your iOS device:</p>\n<p>1/ Download Scriptable app to your iOS device</p>\n<p>2/ Open Scriptable app and click on the “+” on the top right corner</p>\n<p>3/ Rename that script to whatever repo you would like to track</p>\n<p>4/ Copy the code from the file opensource.js on this repository</p>\n<p>5/ Paste it into that new script on your phone</p>\n<p>6/ Change the 4 initial parameters from the file:</p>\n<div class=\"language-python codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-python codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    const WIDGET_TITLE </span><span class=\"token operator\">=</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"openbb.co/open\"</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    const GITHUB_REPO </span><span class=\"token operator\">=</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"OpenBB-finance/OpenBBTerminal\"</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    const PIP_PACKAGE_NAME </span><span class=\"token operator\">=</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"openbb\"</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    const CACHED_DATA_HOURS </span><span class=\"token operator\">=</span><span class=\"token plain\"> </span><span class=\"token number\">1</span><br></span></code></pre></div></div>\n<ul>\n<li>If you only want to track GitHub stats, do <code>PIP_PACKAGE_NAME=\"\"</code>.</li>\n<li>If you only want to track PiPy stats, do <code>GITHUB_REPO=\"\"</code>.</li>\n<li>The <code>CACHED_DATA_HOURS</code> corresponds to the amount of hours where the data is not updated.</li>\n</ul>\n<p>7/ Run script to make sure that it works using the “play button” on the bottom right corner</p>\n<p>8/ Leave the app</p>\n<p>9/ Leave your finger pressed on the iOS homepage</p>\n<p>10/ Click on the “+” on the left top corner</p>\n<p>11/ In the “Search Widgets” tab look for “Scriptable”</p>\n<p>12/ You will see “Run Script” and there are 3 pages. Select the type of widget size that you are interested in</p>\n<p>13/ Select “Add Widget”</p>\n<p>14/ The widget will appear with the sentence “Long press and edit widget to select the script to run”</p>\n<p>15/ Do that and then you will have 3 options:</p>\n<ul>\n<li>Script — Select script name that you renamed to earlier</li>\n<li>When Interacting — Select “Open URL” — A new field will appear with “URL” then provide the link you want to open you cick on the widget (e.g. <a href=\"http://openbb.co/\" target=\"_blank\" rel=\"noopener noreferrer\">http://openbb.co</a>)</li>\n<li>Parameter — If there’s any parameter needed to the script</li>\n</ul>\n<p>16/ Click outside the window, and you should be all set!</p>\n<p>Feel free to contribute to the repository with other examples / templates!</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/keep-track-of-your-startup-metrics-using-a-custom-ios-widget",
            "title": "Keep track of your startup metrics using a custom iOS widget",
            "summary": "Keep track of your startup metrics using a custom iOS widget. This blog post will guide you on how to build a custom iOS widget that displays your startup metrics at all times. The entire code is open source and requires minimal coding skills.",
            "date_modified": "2023-07-29T00:00:00.000Z",
            "tags": [
                "ios",
                "startup",
                "metrics",
                "openbb",
                "scriptable",
                "open-source"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/how-to-use-openai-to-extract-insights-from-team-survey",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2023-07-21-how-to-use-openai-to-extract-insights-from-team-survey.webp\"></p>\n<br>\n<p>This blog post discusses how to use OpenAI to extract insights from team survey data. It covers the motivation behind the project, the requirements, and the implementation process, including the use of the Slack API and Airtable API for automation.</p>\n<p>The open source code is available <a href=\"https://github.com/DidierRLopes/insights-from-team-survey\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"motivation\">Motivation<a href=\"https://didierlopes.com/blog/how-to-use-openai-to-extract-insights-from-team-survey#motivation\" class=\"hash-link\" aria-label=\"Direct link to Motivation\" title=\"Direct link to Motivation\">​</a></h2>\n<p>I’ve been wanting to play with the OpenAI API for a while, but I’ve had higher priority tasks. Yesterday, I thought that I could use the day to do this, but I didn’t want to just try it in a notebook. Instead, I wanted to use it in a real project that could save me time.</p>\n<p>Last week, I posted about how at OpenBB we have developed a monthly team survey and automated the process of requesting information through Slack and Airtable. You can find more on that post <a href=\"https://didierlopes.com/blog/employees-are-leaving-be-proactive-about-employee-feedback\">here</a>.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2023-07-21-how-to-use-openai-to-extract-insights-from-team-survey_1-440b201d561b82d70744ec0367f821d7.webp\" width=\"777\" height=\"348\" class=\"img_ev3q\"></p>\n<p>This made me think that even though I have access to all this data, which OpenBB has made fully available <a href=\"https://openbb.co/open\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>, I still have to spend some time looking at the data to extract insights.</p>\n<img width=\"1397\" alt=\"Screenshot 2023-11-24 at 4 39 41 PM\" src=\"https://didierlopes.com/blog/2023-07-21-how-to-use-openai-to-extract-insights-from-team-survey_2.webp\">\n<p>What if I could automate that analysis using OpenAI? This is what I set out to build, and this post will focus on how I went from idea to implementation.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"requirements\">Requirements<a href=\"https://didierlopes.com/blog/how-to-use-openai-to-extract-insights-from-team-survey#requirements\" class=\"hash-link\" aria-label=\"Direct link to Requirements\" title=\"Direct link to Requirements\">​</a></h2>\n<p>I already had a notebook that I used to analyze our Airtable data with our team survey in it. However, that analysis was quite “heavy,” and it was not straightforward to extract insights. Thus, one of the requirements was to use OpenAI to analyze the team survey feedback for the current month and highlight anything worth mentioning.</p>\n<p>Additionally, I wanted to compare the team’s experience to the prior month to understand if we were improving or not, and identify areas for further improvement. Finally, based on these insights, I wanted OpenAI to suggest what OpenBB, as a company, could do to improve our culture.</p>\n<p>To achieve this using an OpenAI model, I could either export the team survey responses from Airtable in CSV and copy-paste them into ChatGPT, or I could automate the data retrieval using the Airtable API. Being an engineer, why would I do something in 5 minutes when I can spend 1 day automating it? 🤣</p>\n<p>Lastly, I didn’t want to run this script and have to copy-paste the output into our Slack group so that everyone on the team could have access to the overall analysis and provide feedback/suggestions. Therefore, I would like to have a Slack integration that sends the output in a specific formatted way to our Slack channel.</p>\n<p>So, the idea is as follows:</p>\n<ol><li>Retrieve team feedback responses from Airtable</li><li>Extract insights from the team survey data using OpenAI</li><li>Send the insights output to the OpenBB Slack channel</li></ol>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"implementation\">Implementation<a href=\"https://didierlopes.com/blog/how-to-use-openai-to-extract-insights-from-team-survey#implementation\" class=\"hash-link\" aria-label=\"Direct link to Implementation\" title=\"Direct link to Implementation\">​</a></h2>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"slack-api\">Slack API<a href=\"https://didierlopes.com/blog/how-to-use-openai-to-extract-insights-from-team-survey#slack-api\" class=\"hash-link\" aria-label=\"Direct link to Slack API\" title=\"Direct link to Slack API\">​</a></h3>\n<p>First of all, I went to the <a href=\"https://api.slack.com/apps\" target=\"_blank\" rel=\"noopener noreferrer\">Slack API</a> page. There, I created an app named “Employee Voice” and selected the “OpenBB” workspace, as shown below:</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2023-07-21-how-to-use-openai-to-extract-insights-from-team-survey_3-79310871facc059751e1c78efe446923.webp\" width=\"1096\" height=\"1040\" class=\"img_ev3q\"></p>\n<p>After clicking “Create App” I proceeded to update the display information.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2023-07-21-how-to-use-openai-to-extract-insights-from-team-survey_4-46ad5f88eb61afcdad096a663788aa39.webp\" width=\"1400\" height=\"833\" class=\"img_ev3q\"></p>\n<p>Then I go into “Incoming Webhooks” and select the channel I’m interested in posting messages to. That should be all the settings you need to configure for your app.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2023-07-21-how-to-use-openai-to-extract-insights-from-team-survey_5-66ece4070faafd310a10a9cce0069882.webp\" width=\"1126\" height=\"888\" class=\"img_ev3q\"></p>\n<p>The webhook URL will be necessary, so I copied it and added it to the following script. For the channel name, I used my personal name, “<em>Didier Lopes</em>”, since I was just testing if it worked. As for the message, I used the infamous “Hello World” text.</p>\n<p>Here is a sample that you can use to test whether you can successfully send yourself a direct message using the Slack API.</p>\n<div class=\"language-python codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-python codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    SLACK_WEBHOOK_URL</span><span class=\"token operator\">=</span><span class=\"token operator\">&lt;</span><span class=\"token plain\">Webhook URL mentioned above</span><span class=\"token operator\">&gt;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    </span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    insight</span><span class=\"token operator\">=</span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"Hello World\"</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    </span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    payload </span><span class=\"token operator\">=</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">{</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">        </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">'text'</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"> insight</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">}</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    </span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    req </span><span class=\"token operator\">=</span><span class=\"token plain\"> Request</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token plain\">SLACK_WEBHOOK_URL</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> json</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">dumps</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token plain\">payload</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">encode</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">'utf-8'</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    </span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">try</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">        response </span><span class=\"token operator\">=</span><span class=\"token plain\"> urlopen</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token plain\">req</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">        response</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">read</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">        </span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">        </span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">print</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"SUCCESS: Message with insights sent to slack\\n\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    </span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">except</span><span class=\"token plain\"> HTTPError </span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">as</span><span class=\"token plain\"> e</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">        </span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">print</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token string-interpolation string\" style=\"color:rgb(255, 121, 198)\">f\"Request failed: </span><span class=\"token string-interpolation interpolation punctuation\" style=\"color:rgb(248, 248, 242)\">{</span><span class=\"token string-interpolation interpolation\">e</span><span class=\"token string-interpolation interpolation punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token string-interpolation interpolation\">code</span><span class=\"token string-interpolation interpolation punctuation\" style=\"color:rgb(248, 248, 242)\">}</span><span class=\"token string-interpolation string\" style=\"color:rgb(255, 121, 198)\"> </span><span class=\"token string-interpolation interpolation punctuation\" style=\"color:rgb(248, 248, 242)\">{</span><span class=\"token string-interpolation interpolation\">e</span><span class=\"token string-interpolation interpolation punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token string-interpolation interpolation\">reason</span><span class=\"token string-interpolation interpolation punctuation\" style=\"color:rgb(248, 248, 242)\">}</span><span class=\"token string-interpolation string\" style=\"color:rgb(255, 121, 198)\">\\n\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    </span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">except</span><span class=\"token plain\"> URLError </span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">as</span><span class=\"token plain\"> e</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">        </span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">print</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token string-interpolation string\" style=\"color:rgb(255, 121, 198)\">f\"Server connection failed: </span><span class=\"token string-interpolation interpolation punctuation\" style=\"color:rgb(248, 248, 242)\">{</span><span class=\"token string-interpolation interpolation\">e</span><span class=\"token string-interpolation interpolation punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token string-interpolation interpolation\">reason</span><span class=\"token string-interpolation interpolation punctuation\" style=\"color:rgb(248, 248, 242)\">}</span><span class=\"token string-interpolation string\" style=\"color:rgb(255, 121, 198)\">\\n\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><br></span></code></pre></div></div>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"airtable-api\">Airtable API<a href=\"https://didierlopes.com/blog/how-to-use-openai-to-extract-insights-from-team-survey#airtable-api\" class=\"hash-link\" aria-label=\"Direct link to Airtable API\" title=\"Direct link to Airtable API\">​</a></h3>\n<p>At OpenBB, we are using Airtable to automate the monthly team survey questionnaire and store the associated data. I wrote more about that process in <a href=\"https://didierlopes.com/blog/employees-are-leaving-be-proactive-about-employee-feedback\">this blog</a>.</p>\n<p>Now, I want to have programmatic access to this data.</p>\n<p>Firstly, I need to obtain the Airtable API key, which you can get from the <a href=\"https://airtable.com/create/tokens\" target=\"_blank\" rel=\"noopener noreferrer\">Airtable Developer Hub</a>. Secondly, I navigate to Airtable and locate the table that contains the data of interest, as shown below:</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2023-07-21-how-to-use-openai-to-extract-insights-from-team-survey_6-f7f2514f11320403123b4b65ba8eb4c3.webp\" width=\"1400\" height=\"424\" class=\"img_ev3q\"></p>\n<p>The name of the table, “<em>OpenBB_monthly</em>”, corresponds to the “TABLE NAME” that will be necessary. Additionally, when you are on this table view, your URL will have the following format: <a href=\"https://airtable.com/XXX\" target=\"_blank\" rel=\"noopener noreferrer\">https://airtable.com/XXX</a>. That XXX is your “BASE ID,” which will be the final element necessary to retrieve data from Airtable.</p>\n<p>Next, run the following script to ensure that you have access to this data.</p>\n<div class=\"language-python codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-python codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    AIRTABLE_API_KEY</span><span class=\"token operator\">=</span><span class=\"token operator\">&lt;</span><span class=\"token plain\">Located </span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">in</span><span class=\"token plain\"> Airtable Developer Hub</span><span class=\"token operator\">&gt;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    AIRTABLE_BASE_ID</span><span class=\"token operator\">=</span><span class=\"token operator\">&lt;</span><span class=\"token plain\">Located </span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">in</span><span class=\"token plain\"> URL when accessing data</span><span class=\"token operator\">&gt;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    AIRTABLE_TABLE_NAME</span><span class=\"token operator\">=</span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"OpenBB_monthly\"</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    </span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    response </span><span class=\"token operator\">=</span><span class=\"token plain\"> requests</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">get</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">        url</span><span class=\"token operator\">=</span><span class=\"token string-interpolation string\" style=\"color:rgb(255, 121, 198)\">f'https://api.airtable.com/v0/</span><span class=\"token string-interpolation interpolation punctuation\" style=\"color:rgb(248, 248, 242)\">{</span><span class=\"token string-interpolation interpolation\">AIRTABLE_BASE_ID</span><span class=\"token string-interpolation interpolation punctuation\" style=\"color:rgb(248, 248, 242)\">}</span><span class=\"token string-interpolation string\" style=\"color:rgb(255, 121, 198)\">/</span><span class=\"token string-interpolation interpolation punctuation\" style=\"color:rgb(248, 248, 242)\">{</span><span class=\"token string-interpolation interpolation\">AIRTABLE_TABLE_NAME</span><span class=\"token string-interpolation interpolation punctuation\" style=\"color:rgb(248, 248, 242)\">}</span><span class=\"token string-interpolation string\" style=\"color:rgb(255, 121, 198)\">'</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">        headers</span><span class=\"token operator\">=</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">{</span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">'Authorization'</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"> </span><span class=\"token string-interpolation string\" style=\"color:rgb(255, 121, 198)\">f'Bearer </span><span class=\"token string-interpolation interpolation punctuation\" style=\"color:rgb(248, 248, 242)\">{</span><span class=\"token string-interpolation interpolation\">AIRTABLE_API_KEY</span><span class=\"token string-interpolation interpolation punctuation\" style=\"color:rgb(248, 248, 242)\">}</span><span class=\"token string-interpolation string\" style=\"color:rgb(255, 121, 198)\">'</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">}</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    </span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    Check </span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">if</span><span class=\"token plain\"> the data has been loaded correctly</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    </span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">if</span><span class=\"token plain\"> response</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">status_code </span><span class=\"token operator\">==</span><span class=\"token plain\"> </span><span class=\"token number\">200</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">        data </span><span class=\"token operator\">=</span><span class=\"token plain\"> response</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">json</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">[</span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"records\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">]</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    </span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">else</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">        </span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">print</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token string-interpolation string\" style=\"color:rgb(255, 121, 198)\">f\"Error: </span><span class=\"token string-interpolation interpolation punctuation\" style=\"color:rgb(248, 248, 242)\">{</span><span class=\"token string-interpolation interpolation\">response</span><span class=\"token string-interpolation interpolation punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token string-interpolation interpolation\">status_code</span><span class=\"token string-interpolation interpolation punctuation\" style=\"color:rgb(248, 248, 242)\">}</span><span class=\"token string-interpolation string\" style=\"color:rgb(255, 121, 198)\">\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    </span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    </span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">print</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token plain\">data</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><br></span></code></pre></div></div>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"openai-api\">OpenAI API<a href=\"https://didierlopes.com/blog/how-to-use-openai-to-extract-insights-from-team-survey#openai-api\" class=\"hash-link\" aria-label=\"Direct link to OpenAI API\" title=\"Direct link to OpenAI API\">​</a></h3>\n<p>Finally, go to <a href=\"https://platform.openai.com/account/api-keys\" target=\"_blank\" rel=\"noopener noreferrer\">OpenAI Developer platform</a> and grab your OpenAI API key.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2023-07-21-how-to-use-openai-to-extract-insights-from-team-survey_7-f5fee2d671e1b03200e34da6ac9d550e.webp\" width=\"1400\" height=\"620\" class=\"img_ev3q\"></p>\n<p>Once you have that, you are pretty much ready to test whether this works or not. In this case, we assume you have access to the data from Airtable, so you can test if the OpenAI code is set up correctly with the following:</p>\n<div class=\"language-python codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-python codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    data_previous_month</span><span class=\"token operator\">=</span><span class=\"token operator\">&lt;</span><span class=\"token plain\">dataframe </span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">with</span><span class=\"token plain\"> raw survey data </span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">from</span><span class=\"token plain\"> previous month</span><span class=\"token operator\">&gt;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    data_current_month</span><span class=\"token operator\">=</span><span class=\"token operator\">&lt;</span><span class=\"token plain\">dataframe </span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">with</span><span class=\"token plain\"> raw survey data </span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">from</span><span class=\"token plain\"> current month</span><span class=\"token operator\">&gt;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    current_month</span><span class=\"token operator\">=</span><span class=\"token operator\">&lt;</span><span class=\"token plain\">current month date</span><span class=\"token operator\">&gt;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    </span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    openai</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">api_key</span><span class=\"token operator\">=</span><span class=\"token operator\">&lt;</span><span class=\"token plain\">Located </span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">in</span><span class=\"token plain\"> OpenAI Developer platform</span><span class=\"token operator\">&gt;</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    response </span><span class=\"token operator\">=</span><span class=\"token plain\"> openai</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">ChatCompletion</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">create</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    model</span><span class=\"token operator\">=</span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"gpt-4\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\">  </span><span class=\"token comment\" style=\"color:rgb(98, 114, 164)\"># you can use a different model</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    messages</span><span class=\"token operator\">=</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">[</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">            </span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">{</span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"role\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"system\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"content\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"You are a Chief of Staff with a MSc. in Data analysis and are trying to improve the culture of the company.\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">}</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">            </span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">{</span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"role\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"user\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> </span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">            </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"content\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"> </span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">                </span><span class=\"token string-interpolation string\" style=\"color:rgb(255, 121, 198)\">f\"\"\"</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token string-interpolation string\" style=\"color:rgb(255, 121, 198)\">        This table represents the company survey for the previous month: </span><span class=\"token string-interpolation interpolation punctuation\" style=\"color:rgb(248, 248, 242)\">{</span><span class=\"token string-interpolation interpolation\">data_previous_month</span><span class=\"token string-interpolation interpolation punctuation\" style=\"color:rgb(248, 248, 242)\">}</span><span class=\"token string-interpolation string\" style=\"color:rgb(255, 121, 198)\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token string-interpolation string\" style=\"color:rgb(255, 121, 198)\">    </span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token string-interpolation string\" style=\"color:rgb(255, 121, 198)\">        This table represents the company survey for this month: </span><span class=\"token string-interpolation interpolation punctuation\" style=\"color:rgb(248, 248, 242)\">{</span><span class=\"token string-interpolation interpolation\">data_current_month</span><span class=\"token string-interpolation interpolation punctuation\" style=\"color:rgb(248, 248, 242)\">}</span><span class=\"token string-interpolation string\" style=\"color:rgb(255, 121, 198)\">.</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token string-interpolation string\" style=\"color:rgb(255, 121, 198)\">    </span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token string-interpolation string\" style=\"color:rgb(255, 121, 198)\">        Based on this data, can you do 3 things:</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token string-interpolation string\" style=\"color:rgb(255, 121, 198)\">        </span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token string-interpolation string\" style=\"color:rgb(255, 121, 198)\">        1. Summarize main differences since last month</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token string-interpolation string\" style=\"color:rgb(255, 121, 198)\">        2. Summarize main highlights for current month</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token string-interpolation string\" style=\"color:rgb(255, 121, 198)\">        3. Create suggestions for what could be done to improve those areas</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token string-interpolation string\" style=\"color:rgb(255, 121, 198)\">        </span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token string-interpolation string\" style=\"color:rgb(255, 121, 198)\">        Please use the following format for the output:</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token string-interpolation string\" style=\"color:rgb(255, 121, 198)\">            As the title use the following: Insights from team survey in </span><span class=\"token string-interpolation interpolation punctuation\" style=\"color:rgb(248, 248, 242)\">{</span><span class=\"token string-interpolation interpolation\">current_month</span><span class=\"token string-interpolation interpolation punctuation\" style=\"color:rgb(248, 248, 242)\">}</span><span class=\"token string-interpolation string\" style=\"color:rgb(255, 121, 198)\">.</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token string-interpolation string\" style=\"color:rgb(255, 121, 198)\">            Follow the title by 2 line breaks.</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token string-interpolation string\" style=\"color:rgb(255, 121, 198)\">            Use bullet points within each of the points mentioned above.</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token string-interpolation string\" style=\"color:rgb(255, 121, 198)\">            Between the 3 points, use 1 line breaks, a line with ----------------------- and another line break.</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token string-interpolation string\" style=\"color:rgb(255, 121, 198)\">            Use `` when referring to a component like `Reward` or `Growth`.</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token string-interpolation string\" style=\"color:rgb(255, 121, 198)\">            Do not use asterisks '*' or '**'.</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token string-interpolation string\" style=\"color:rgb(255, 121, 198)\">            When referring to to Engineering or Product, Marketing, Design, Finance wrap them around asterisk, e.g. _Engineering_.</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token string-interpolation string\" style=\"color:rgb(255, 121, 198)\">                \"\"\"</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">            </span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">}</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">        </span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">]</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    </span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    </span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">print</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token plain\">response</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">choices</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">[</span><span class=\"token number\">0</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">]</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">message</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">content</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><br></span></code></pre></div></div>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"glue-it-together\">Glue it together<a href=\"https://didierlopes.com/blog/how-to-use-openai-to-extract-insights-from-team-survey#glue-it-together\" class=\"hash-link\" aria-label=\"Direct link to Glue it together\" title=\"Direct link to Glue it together\">​</a></h2>\n<p>Once you have the scripts, merging them is straightforward. I will show you what the input vs. output looks like.</p>\n<p>Here is <a href=\"http://openbb.co/\" target=\"_blank\" rel=\"noopener noreferrer\">OpenBB</a>’s team survey data from June of 2023:</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2023-07-21-how-to-use-openai-to-extract-insights-from-team-survey_8-ab4a56311ab612a1cae17dcff383dcf7.webp\" width=\"1400\" height=\"299\" class=\"img_ev3q\"></p>\n<p>If I run the script here, as shown below (yes, you guessed it right — I open-sourced this project as usual. I hope you and your team find it useful):</p>\n<div class=\"language-console codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-console codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    $ python extract_insights_from_last_team_survey.py</span><br></span></code></pre></div></div>\n<p>This is the expected output if the script runs successfully.</p>\n<div class=\"language-console codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-console codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    Loading environment variables...</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    Loading team survey data from Airtable...</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    Processing data from Airtable...</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    Extracting insights from team survey data...</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    Sending insights to Slack through a message...</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    SUCCESS: Message with insights sent to slack</span><br></span></code></pre></div></div>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2023-07-21-how-to-use-openai-to-extract-insights-from-team-survey_9-cca84eb660ce88302c80a0d57b8acd42.webp\" width=\"1400\" height=\"963\" class=\"img_ev3q\"></p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"automate-with-github-workflow\">Automate with GitHub workflow<a href=\"https://didierlopes.com/blog/how-to-use-openai-to-extract-insights-from-team-survey#automate-with-github-workflow\" class=\"hash-link\" aria-label=\"Direct link to Automate with GitHub workflow\" title=\"Direct link to Automate with GitHub workflow\">​</a></h2>\n<p>We’re almost there! It doesn’t make sense for us to manually run this script every month. Plus, software engineers are known for their laziness (which is actually a <a href=\"https://thethreevirtues.com/\" target=\"_blank\" rel=\"noopener noreferrer\">virtue of a great programmer</a>), so let’s create a GitHub action to automate this process.</p>\n<p>To begin, create a file called “main.yml” in the “.github/workflows” directory.</p>\n<p><a href=\"https://github.com/DidierRLopes/insights-from-team-survey/blob/main/.github/workflows/main.yml\" target=\"_blank\" rel=\"noopener noreferrer\">This workflow</a> will be divided into three main sections:</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"when\">When<a href=\"https://didierlopes.com/blog/how-to-use-openai-to-extract-insights-from-team-survey#when\" class=\"hash-link\" aria-label=\"Direct link to When\" title=\"Direct link to When\">​</a></h3>\n<p>Specifies when this GitHub action should run.</p>\n<div class=\"language-console codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-console codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    on:</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">      push:</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">        branches:</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">          - main</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">      schedule:</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">        - cron: '0 0 3 * *'</span><br></span></code></pre></div></div>\n<p>The first section, “on: push: branches: [main]” means that whenever there is a code push to the “main” branch, this workflow will be triggered. This feature allows us to quickly test whether the action is functioning as expected.</p>\n<p>The “schedule-cron” makes it so that the yaml gets run at a specific dates and times.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"secrets\">Secrets<a href=\"https://didierlopes.com/blog/how-to-use-openai-to-extract-insights-from-team-survey#secrets\" class=\"hash-link\" aria-label=\"Direct link to Secrets\" title=\"Direct link to Secrets\">​</a></h3>\n<p>What do we need in advance for this to work?</p>\n<div class=\"language-console codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-console codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    env:</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">      SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">      OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">      AIRTABLE_API_KEY: ${{ secrets.AIRTABLE_API_KEY }}</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">      AIRTABLE_BASE_ID: ${{ secrets.AIRTABLE_BASE_ID }}</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">      AIRTABLE_TABLE_NAME: ${{ secrets.AIRTABLE_TABLE_NAME }}</span><br></span></code></pre></div></div>\n<p>All of these variables need to be set as action secrets. You can do this by selecting the “Settings” tab above, then going into “Scripts and variables,” and selecting “New repository secret.” Fill in the information accordingly, as shown below:</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2023-07-21-how-to-use-openai-to-extract-insights-from-team-survey_10-c6504edb4cd89761a7199761043f7265.webp\" width=\"1400\" height=\"798\" class=\"img_ev3q\"></p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"workflow\">Workflow<a href=\"https://didierlopes.com/blog/how-to-use-openai-to-extract-insights-from-team-survey#workflow\" class=\"hash-link\" aria-label=\"Direct link to Workflow\" title=\"Direct link to Workflow\">​</a></h3>\n<p>What commands are we running with this GitHub action? In our case, these are the ones we are interested in.</p>\n<div class=\"language-console codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-console codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    jobs:</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">      build:</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">        runs-on: ubuntu-latest</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    </span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">        steps:</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">          - name: checkout repo content</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">            uses: actions/checkout@v2</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    </span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">          - name: setup python</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">            uses: actions/setup-python@v2</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">            with:</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">              python-version: 3.9</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    </span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">          - name: install python packages</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">            run: |</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">              python -m pip install --upgrade pip</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">              pip install python-dotenv</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">              pip install pandas</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">              pip install openai</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    </span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">          - name: extract insights from team feedback</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">            run: |</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">              python extract_insights_from_last_team_survey.py</span><br></span></code></pre></div></div>\n<p>And that’s it! You now have a complete automation pipeline from employee feedback to insights within seconds.</p>\n<p>I hope you enjoyed reading this post, and I would love to hear your feedback. Do you appreciate the level of technical detail I go into, or would you prefer less?</p>\n<p>Any comments are very helpful. Thank you!</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/how-to-use-openai-to-extract-insights-from-team-survey",
            "title": "How to Use OpenAI to Extract Insights from Team Survey",
            "summary": "This blog post discusses how to use OpenAI to extract insights from team survey data. It covers the motivation behind the project, the requirements, and the implementation process, including the use of the Slack API and Airtable API for automation.",
            "date_modified": "2023-07-21T00:00:00.000Z",
            "tags": [
                "openai",
                "team-survey",
                "insights",
                "automation",
                "slack",
                "airtable"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/why-the-need-for-an-open-source-investment-research-platform",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2023-07-16-why-the-need-for-an-open-source-investment-research-platform.webp\"></p>\n<br>\n<p>OpenBB Terminal, an open-source investment research platform, is transforming the financial industry by addressing issues like data licensing, full-price bundle, lack of transparency and customization, and the need for a diverse community. This post explores why open source is crucial for us and the main problems in the space.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>Having a closed source OpenBB Terminal was never on the table.</p>\n<p>The <a href=\"https://github.com/OpenBB-finance/OpenBBTerminal\" target=\"_blank\" rel=\"noopener noreferrer\">OpenBB Terminal</a> is the platform it is today due to its open source nature. Launched almost 2.5 years ago, the interest on this platform was clear — aggregating an impressive 4000 stars on GitHub in under 24 hours from launch.</p>\n<p>This number kept on growing along with the community (most of which gathers on <a href=\"http://openbb.co/discord\" target=\"_blank\" rel=\"noopener noreferrer\">our Discord server</a>) and allowed us to create the company OpenBB, see the story <a href=\"http://openbb.co/blog/gme-didnt-take-me-to-the-moon-but-gamestonk-terminal-did\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2023-07-16-why-the-need-for-an-open-source-investment-research-platform_1-703cb1bd40ac73da606150d80b4cf63a.webp\" width=\"1400\" height=\"790\" class=\"img_ev3q\"></p>\n<p>But why is open source so important for us? To understand this, it’s important for us go over the main problems in the space.</p>\n<ol><li>Data licensing</li><li>Full-price bundle</li><li>Transparency and customization</li><li>Community</li></ol>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"data-licensing\">Data licensing<a href=\"https://didierlopes.com/blog/why-the-need-for-an-open-source-investment-research-platform#data-licensing\" class=\"hash-link\" aria-label=\"Direct link to Data licensing\" title=\"Direct link to Data licensing\">​</a></h2>\n<p>Current monopolies spend an enormous amount of capital on financial data licensing. There are dozens of different asset classes (equities, options, crypto, NFTs, forex, bonds, ETFs, mutual funds, …) and these often vary based on geography. In addition, alternative datasets have grown a lot in popularity as they can provide a hedge in the market (e.g. a hurricane can impact orange juice futures).</p>\n<p>That makes the overall investment research industry a very tough market to compete. Startups cannot disrupt the space without a massive capital injection. Explaining why the data offered by startups usually focuses on a certain asset class, in a certain geography.</p>\n<p>This is why OpenBB doesn’t own the data (similar to Uber not owning cars, Airbnb not owning apartments, Deliveroo not owning restaurants). OpenBB wants to be the infrastructure layer between data sources and users.</p>\n<p>This is the typical two-sided market, where on the one hand users benefit from having access to multiple datasets in one place, and on the other hand data sources benefit from having users on our platform as they can monetize their data. This allows us to focus on the product while our number of data integrations and users grows.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"full-price-bundle\">Full-price bundle<a href=\"https://didierlopes.com/blog/why-the-need-for-an-open-source-investment-research-platform#full-price-bundle\" class=\"hash-link\" aria-label=\"Direct link to Full-price bundle\" title=\"Direct link to Full-price bundle\">​</a></h2>\n<p>Current incumbents pricing is usually a complete bundled offering. This means that regardless of what you are utilizing in terms of both breadth and depth, you pay the full price tag. A good analogy is like a restaurant ONLY having a buffet when all you want is a bottle of water, or some chips.</p>\n<p>What happens is that a user ends up paying for data that they are not using. In 2023, this is a very outdated take. Companies are looking to get leaner, and it doesn’t make sense to pay for data that you aren’t leveraging.</p>\n<p>Being the infrastructure between users and data sources allows you to create value to both. Users will have access to all the data they want and pay for the ones they use, and data sources will have access to a big pool of users.</p>\n<p>In addition some data providers (e.g. a team of machine learning engineers) will not need to create a dashboard for their users to visualize their data and hire a team to start a sales/marketing motion, as they will be able to rely on OpenBB’s infrastructure.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"transparency-and-customization\">Transparency and customization<a href=\"https://didierlopes.com/blog/why-the-need-for-an-open-source-investment-research-platform#transparency-and-customization\" class=\"hash-link\" aria-label=\"Direct link to Transparency and customization\" title=\"Direct link to Transparency and customization\">​</a></h2>\n<p>Current incumbents have built several in-house financial models. Although these are often customizable, their customization is typically limited. That is because what is usually customizable are the values/weights, but not necessarily the formulas — that is kept hidden in their source code. This is an issue because that code cannot be validated and users cannot modify it.</p>\n<p>With open source, the story is completely different. Users can see every single line of code and therefore, not only audit the code quality but adapt the models/formulas to their own needs. At the end of the day, there is no point in re-inventing the wheel for financial theory that has been around for decades.</p>\n<p>By having the code open source, users can rely on the fact that these formulas have been validated/tested by thousands or millions of users and therefore, there’s a very low chance that these are wrong. In addition, users are more secure because they can investigate the code and check/fix any vulnerabilities.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"community\">Community<a href=\"https://didierlopes.com/blog/why-the-need-for-an-open-source-investment-research-platform#community\" class=\"hash-link\" aria-label=\"Direct link to Community\" title=\"Direct link to Community\">​</a></h2>\n<p>One of the best parts of open source is the integrated community that it creates. This attracts people from every background, gender or ethnicity. Such a pool of diversity allows for better ideas and pushes a project further. With people from the community being able to contribute, this also drives innovation.</p>\n<p>OpenBB has been driven a lot by the community so far. What started as a terminal mostly focused on equities, soon evolved into including a broad range of datasets and considering several geographies. For instance: A contributor from Sweeden integrated Avanza API to the mutual funds menu that would only appear if users were looking into mutual funds from Sweden — this shows the power of community.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2023-07-16-why-the-need-for-an-open-source-investment-research-platform_2-23efa3c590a05db8e44fd5f0366bf782.webp\" width=\"888\" height=\"499\" class=\"img_ev3q\"></p>\n<p>We are close to 23,000 stars. If you haven’t already, starring our project would mean the world.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2023-07-16-why-the-need-for-an-open-source-investment-research-platform_3-e1c7a7c94007a0d202ad5fd78e28aea2.webp\" width=\"800\" height=\"533\" class=\"img_ev3q\"></p>\n<p>Any feedback is welcome 🙏🏽</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/why-the-need-for-an-open-source-investment-research-platform",
            "title": "Why the need for an open source investment research platform?",
            "summary": "OpenBB Terminal, an open-source investment research platform, is transforming the financial industry by addressing issues like data licensing, full-price bundle, lack of transparency and customization, and the need for a diverse community. This post explores why open source is crucial for us and the main problems in the space.",
            "date_modified": "2023-07-16T00:00:00.000Z",
            "tags": [
                "open-source",
                "investment-research",
                "data-licensing",
                "transparency",
                "community"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/from-open-source-to-open-startup",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2023-07-06-from-open-source-to-open-startup.webp\"></p>\n<br>\n<p>From Open Source to Open Startup: A journey of OpenBB towards transparency in the financial world.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>Being open source isn't enough, at OpenBB we want to accelerate the transparency in the financial world.</p>\n<p>I want to start this blogpost by introducing the concept of an open startup. As this phrase can often be interpreted differently, here's the standard definition that ChatGPT gave me:</p>\n<blockquote>\n<p><em>\"An open startup is a company that practices open innovation and transparent communication with its stakeholders, including customers, employees, and investors. This means that the company is willing to share information about its products, services, and business operations with the public and is open to input and feedback from all stakeholders.</em></p>\n</blockquote>\n<br>\n<blockquote>\n<p><em>Open startups typically have a strong focus on collaboration and community building, and they often use open source technology and principles in their operations. Some open startups may also be structured as cooperative or worker-owned enterprises, in which ownership and decision-making power are shared among employees.”</em></p>\n</blockquote>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"why-now\">Why now?<a href=\"https://didierlopes.com/blog/from-open-source-to-open-startup#why-now\" class=\"hash-link\" aria-label=\"Direct link to Why now?\" title=\"Direct link to Why now?\">​</a></h2>\n<p>I've been learning about the open startup movement for a while now and I always knew that I wanted OpenBB to follow this trend. At the end of the day, I want us to accelerate the openness and transparency in the financial world.</p>\n<p>But until recently, this wasn't one of our top priorities. This all changed when the cryptocurrency exchange FTX collapsed. This was a house of cards and they stood for everything but transparency — not only with their users but also with their shareholders and team alike!</p>\n<p>John J. Ray III who has spent a career tackling large corporate failures involving allegations of criminal activity (like Enron), was appointed CEO of FTX to deal with the bankruptcy, and this is one of his quotes to the US congress:</p>\n<blockquote>\n<p><em>\"Never in my career have I seen such an utter failure of corporate controls at every level of an organization, from the lack of financial statements to a complete failure of any internal controls or governance whatsoever\"</em></p>\n</blockquote>\n<br>\n<p>OpenBB wants to pave the way of transparency in the financial world.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"why-open\">Why open?<a href=\"https://didierlopes.com/blog/from-open-source-to-open-startup#why-open\" class=\"hash-link\" aria-label=\"Direct link to Why open?\" title=\"Direct link to Why open?\">​</a></h2>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"transparency\">Transparency<a href=\"https://didierlopes.com/blog/from-open-source-to-open-startup#transparency\" class=\"hash-link\" aria-label=\"Direct link to Transparency\" title=\"Direct link to Transparency\">​</a></h3>\n<p>Transparency across team, shareholders, users and new hires is key. Everyone can see our growth in the same location; A single source of truth accessible to everyone at all times. We already have our code open source, which shows transparency in our engineering, so it only makes sense for us to behave in the same way with our business.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"accountability\">Accountability<a href=\"https://didierlopes.com/blog/from-open-source-to-open-startup#accountability\" class=\"hash-link\" aria-label=\"Direct link to Accountability\" title=\"Direct link to Accountability\">​</a></h3>\n<p>Everyone will know how we're doing, for better or worse. This will make us feel responsible to show accurate sustainable growth as this information becomes public. Since everyone has equity in the company, this will be our own skin in the game.</p>\n<p>When people ask, \"How is OpenBB going?\" this can be answered with a single link to our open page.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"community-building\">Community building<a href=\"https://didierlopes.com/blog/from-open-source-to-open-startup#community-building\" class=\"hash-link\" aria-label=\"Direct link to Community building\" title=\"Direct link to Community building\">​</a></h3>\n<p>Every company is trying to build a community these days, but building a community is hard. By having all of our information publicly available, anyone from the community will know how we are doing at all times — similar to what the team, shareholders and investors know.</p>\n<p>This helps to build trust in OpenBB and allow us to attract and retain talented employees who value transparency and an open culture.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"marketing\">Marketing<a href=\"https://didierlopes.com/blog/from-open-source-to-open-startup#marketing\" class=\"hash-link\" aria-label=\"Direct link to Marketing\" title=\"Direct link to Marketing\">​</a></h3>\n<p>Users will be able to share our open page to share OpenBB metrics with other users, which will help to increase awareness for us.</p>\n<p>In addition, we want to become leaders of open culture in the financial world, which is known for being a very closed industry. We want to influence companies in this sector and start a movement.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"fundraising\">Fundraising<a href=\"https://didierlopes.com/blog/from-open-source-to-open-startup#fundraising\" class=\"hash-link\" aria-label=\"Direct link to Fundraising\" title=\"Direct link to Fundraising\">​</a></h3>\n<p>Since starting OpenBB, I've met well over 50 different investors, even without actively fundraising. Whilst this is a great way to start relationships, it's not sustainable as it takes valuable time away from talking with users/customers (and let's be honest, even developing :slight_smile:). So by having an open page, we will be able to discuss our growth async and more efficiently. And then, when we are actively fundraising, we can focus on the details.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"how-will-it-be-done\">How will it be done?<a href=\"https://didierlopes.com/blog/from-open-source-to-open-startup#how-will-it-be-done\" class=\"hash-link\" aria-label=\"Direct link to How will it be done?\" title=\"Direct link to How will it be done?\">​</a></h2>\n<p>We are adding all our metrics and stats to <a href=\"https://openbb.co/open\" target=\"_blank\" rel=\"noopener noreferrer\">/open</a>.</p>\n<p>Our open metrics will contain 4 main distinct sections to start with:</p>\n<h4 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"social-media-metrics\">Social Media metrics<a href=\"https://didierlopes.com/blog/from-open-source-to-open-startup#social-media-metrics\" class=\"hash-link\" aria-label=\"Direct link to Social Media metrics\" title=\"Direct link to Social Media metrics\">​</a></h4>\n<p>Twitter followers, Discord users, LinkedIn followers, YouTube views, Reddit followers. Allows to understand the strength of our community in the social media channels that we focus on.</p>\n<h4 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"team-stats\">Team stats<a href=\"https://didierlopes.com/blog/from-open-source-to-open-startup#team-stats\" class=\"hash-link\" aria-label=\"Direct link to Team stats\" title=\"Direct link to Team stats\">​</a></h4>\n<p>Team distribution and employee engagement coming soon. Allows to understand where we are based and employee experience at OpenBB</p>\n<h4 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"product-metrics\">Product metrics<a href=\"https://didierlopes.com/blog/from-open-source-to-open-startup#product-metrics\" class=\"hash-link\" aria-label=\"Direct link to Product metrics\" title=\"Direct link to Product metrics\">​</a></h4>\n<p>OpenBB Hub users, OpenBB Bot, OpenBB SDK and OpenBB Terminal. Allows to hold us accountable for our user growth and the usage that our products have</p>\n<h4 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"developer-metrics\">Developer metrics<a href=\"https://didierlopes.com/blog/from-open-source-to-open-startup#developer-metrics\" class=\"hash-link\" aria-label=\"Direct link to Developer metrics\" title=\"Direct link to Developer metrics\">​</a></h4>\n<p>Stars, forks, merged pull-requests, closed issues, contributors. Keep up-to-date with our development speed and how engaged the open source community is.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>For all the metrics that are open source, there will be an ⓘ in the top right to share information on why this chart was made open source and why it's important to us.</p>\n<p>Once a metric is open, we do not intend to close it ever again, that is why all the metrics we are making public have gone through a thorough reasoning process and there's enough contextual information to understand its meaning.</p>\n<p>If you can think of a metric that you would like to see on our open page, please feel free to DM me.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/from-open-source-to-open-startup",
            "title": "From Open Source to Open Startup",
            "summary": "From Open Source to Open Startup. A journey of OpenBB towards transparency in the financial world.",
            "date_modified": "2023-07-06T00:00:00.000Z",
            "tags": [
                "open-source",
                "open-startup",
                "transparency",
                "openbb",
                "startup-culture",
                "business-metrics",
                "community"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/employees-are-leaving-be-proactive-about-employee-feedback",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2023-06-29-employees-are-leaving-be-proactive-about-employee-feedback.webp\"></p>\n<br>\n<p>Employees are leaving? Be proactive about employee feedback. This blogpost discusses the importance of employee feedback and how we at OpenBB are ensuring high employee engagement through a periodic feedback survey.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>This blogpost shows the measures we are taking to ensure we have high employee engagement at OpenBB through a periodic feedback survey.</p>\n<p>When we started OpenBB, I was absolutely obsessed about our product. All my focus and time was dedicated to building our suite of products (OpenBB Terminal, OpenBB SDK or OpenBB Bot), or talking about these with our users. I care deeply about the OpenBB team, but I expected everyone to be as motivated as me, 24/7.</p>\n<p>But things just don’t work that way. Although we always have a fun quarterly event online, that isn’t enough. Everyone knows that I’m a big fan of remote work, but one clear down side of it is the lack of contact and face to face conversations which makes employee engagement more volatile. I say this, because I believe that when your team is together in the same space, it’s easier to thrive off each others excitement and motivation.</p>\n<p>Soon enough, I realized that <em>“alone you can go faster, but with a team you can go far”</em>. This is when I started putting time into understanding what we could be doing better to improve our work culture.</p>\n<p>Some things that we have now put into place include:</p>\n<ul>\n<li>\n<p>We updated the company values as a team, based on what we currently had that they were proud of and where they would like us to be in the future. In a startup, where the pace is incredibly fast and the team is constantly changing, I strongly believe that the values change over time too.</p>\n</li>\n<li>\n<p>We had an <a href=\"https://www.youtube.com/watch?time_continue=48&amp;v=ThtSC8s0h6I&amp;embeds_referring_euri=https%3A%2F%2Fopenbb.co%2Fblog&amp;source_ve_path=MzY4NDIsMjg2NjMsMjg2NjY&amp;ab_channel=OpenBB\" target=\"_blank\" rel=\"noopener noreferrer\">OpenBB rap</a> made by a freestyler for our OpenBB Christmas event.</p>\n</li>\n<li>\n<p>We started pushing for more transparency. We were already very transparent internally, but now we started to push this value externally too. Everyone in the company has skin in the game, this allows the team to feel as accountable for the metrics as I do. I wrote more about this in this blogpost: <a href=\"https://didierlopes.com/blog/from-open-source-to-open-startup\">From open source to open startup</a>, and I am currently working on the OpenBB Handbook too.</p>\n</li>\n<li>\n<p>I started having office hours, where I can spend the time with the team chatting about anything (product, strategy, engineering, storytelling, even fundraising). The team knows that I’m usually available, but having that 1 hour blocked gives them the confidence to know that that time booked in the day.</p>\n</li>\n</ul>\n<p>However, there was something critical missing. I will explain what it is by using what I learned at university (that way I can say that my MSc in Control Systems was indeed useful for OpenBB 🙃).</p>\n<p>What we had built is an open loop control system, and it looks something like this:</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"data:image/webp;base64,UklGRq4VAABXRUJQVlA4IKIVAADQawCdASoMA3IAPjEYi0OiIaESWdUIIAMEtLd8H5OqH6aiD1/VrvY3i/y6wDWRoPZ+k/+A/DPwL/vP5C+ef4h8q/UPyR/tf7S+6h/HdDj/R+iH80+in3L+6fz7/Nf2P9yvfz/IflP/UuQI/Hv4X/cf0x/xP9z/bP6Q/Se3jpt/lPUR9ffhf+K/x/8t/1H9i/bz6nfLf9J+WfSC/zP+C/4b9Nf9P/hv/37hH+y7jHsCf1f+Ef7f9Nv+p/ivpj/Cv+t/vf5r/3f85///VI/5PuN/zn+Cf7b9Mv+j/iP///5PsA////57L/9AP///8SOaIi1cdCABEWrjoQAIi1cdCABEWrjoQAIi1cdB/2Tt1/k0iHUR9MiDI+9PdKYhBZlTMhih4A4kKDZ51rTmq/UO79c0tKQVjmUkZ+a+hOh9cmqUedprB5gFeVWZ531He8v3syTmx3TauctMhbFqN4g+v9VJ+QBUUbuEVT1GtGy55M5isC6nsd8EVhVvnWoOMxi6F0i9zlXM8linqf5xgR5WyfBsdQHcE+Q3+oNr9X/S9vwDIMAJ7EHtG5vHgs1z1XxHXSvLnJnMWGxY/V93yPhd+6u58sK45kkbO3wxe/crR9aGpx36xbw16H3GgcEkrzkdCbov0bpY8uiNSz88H0OeMO3mm0rAJJPrGO95MBmFmxwJB4WdtSe5XyGJa1AR6jb9NdCbXheEbiLQTLFIOrBqZujI+o5HM1VOvWfYzBB6WMqQz8dAKjXq7n1QvtCDYjqJwDcNbYj5dDVuIf7CmOkBa6qT1uZ35XRFQvnD9HRyYe8VT/tZvnGg+2NcwwwjmQ1HB8vvf3ZCWEv7pUxt58eEQy6xwm0TKe5VboIV/xzwFNnOtUZK6ITn+6ZiABAQ+MQkRUt68biPJo1v1Auh5KLsj45DOwEJNfx9kwpSTkey0kwdVwJoLqZs0EhjpEimiAfdrG6AhAWb5a2JV1mqRxRoBl14B4MJ9GEHuRs66u6nIpElWoA8k9z82jkHz5GzOi0YX1xLj/765jSJM+x8or982urCdYPXzkpVmcS3WlhGVyr3j5rR9bpGFX2cv55a/TT581Xg9m4qszzvraDqrM8762NCABE7+tjQgARFq46EACItXHQgARFq46EACItXHQgARFq46EACIsAAAP77KRAAxa6JAN8f9CzktveWbKRvIvSQcSXpTJPYfhavgb5XhTuEB9OCzCxcOABzIyS2VB9s/aPY4Fp6qb7w+25otPGLoq8EsE4mdDkrM0fl9tu49j+g3c7N1AeF0un5Wf4jPQbQakl/JHhuInJbsKP1ALUsuaXRgv6WeYuwXx+HWpzaGlECYo7UrZgNnD9YwCOP57YAbTBBWAIOckbF1YiLf95zwFHPh2sQgouMB58GUd+1CrzV+y6IPKtJ0Vv8xLx30+n0kPd8EfnHjeqm+2kGHPbVfFXvxeCAg9YMh4AfxnONJW7ir0GaKJvKWj0PGeRZ0Als8ONJYv41ZLcbADAR2GhdA+5vN/9uwKtc3EPGAKtnAg1WrtPXx5l+JGNrztnXPkJtynNFL70Y9VTst1lLv/fqp1vuBxBudbwj+nRJOuAqGYSZ6GNUwDSZ7+LECXGy0wjbSLlDPX738dfA/+dqyHorKrI1jOmrOjTrc4tAH2/u90foPuYW9RO1eVzGjRFtIyQRrmhsj08bNLeKNI3e5bW2XrokOq90R2Zvat7s6pLbVVmV99iNUqsEOA/ofNmzmuqD6PbRzf9+ich+1sdh5huarnAy9S61tmcIMBb0+Kxl5VH+L0YSPMymOf2tIIiOR5vuPHN0h1zj7GtjckAp1VtT9nJ0t762ZoAFw2us+XrEW4IKHH7spBQ54d+GB4LdTexx5dEWxSWjPnZpNyLr3M2M64NXFSLNUDt8QJxrzlCCr1hNu4L/5jRrJ0RckqP/z2mf+sWuIv1Lmf9nj7KqZdymB2rs9QqX7Y0YxuPD2G0frmRIpY6gN2/+TTTPpLndfOCC3uLMAVRgjXquBMcpI9pJk970n/JCmoxU3jhft4DspwgbaRNlGJecN+IQMcbvonbkl345lelyhYTK8QpYuqJhvlJL/XNB/iZ8LPcRKRs+zKF4ZrXQ1f/6YeO3YHW/PAaac9M+7XGjZaOTTA3kGIxcSOOI8FBcNgg1CRdvht94ARfsIl43n9dKQDJHkwe3y6lK9BiuXFeqMQbeXIFf02lz3nyReBegkxJEeoFWLrw8rCDy5CxfIBcqR4D6gntzQmh2VWcUoEBoJR/aPy9m0OOGCcVYFyc1k2Kw75QDjn1mZKOthWqS6HrdP668733WrdhO0vpNaqgL4vnX4L3vVSseIXSqtKB2jTDkhjZu0dU/wTMwZDIV9whuB8uaLNizTGZRUUb+nsyb2M3FhevTZJpYMDi9c245MDMHzOL8Up+8nFT/rxtyQmPTlUKQUUo9MMA76UcxSI/S3kBDjlojQ90UPsX3/kmQB1LHZioN9cqt7M2z1/1KljaF93huY1sks9MkCW/Wvds+ZlrSidQ7G1uJIns1pTW1iTVv9IJxVTZzwOa+JmA0A30RlYgWMIfkuWCaJf+3aNpyOf/4/O8OpM/EiwlopO2X78xLz6KBvGn5fqgrWU9Do5G83O8ZuLD54ZPbfSIbRsLNhosTPvg0+8ecFFbDMh0pZh3SP2U/lajIst6uNfIub9lv+0FTvCwqs8zBLiFEfcARlE9zTZL/RE9pbIlsMUrCes448I/HaWm8GTyoxVnZtNK1TvK7p+P91kmmo+My6vSUd4U77PsSiP/54N31hNWY4UHrvrQ9VJzn53AnrzFzmOw8kPGlOEqieKqp9VAR2q5HLrjGiKxAjVunIfnNtAyKaN2NXyZQzXdfv1/CWnyZp69PdFj54vvwOWZpDqRTF5hGPgKe1108fpaKcItT+xXlAnYyAdOlBzi1ZyxOK6feG9CQDL4bg8hWb8sxgMATU4FbOPhTeA1ejOINR3BBiwfWBAuaBeJsI1fAzgveUz9s+3pGy2mZ6f4WVtdkcAVz72cvH3zrhFI0dalHMwVApmRdjtXWM2mWogFmQcncrxkBbqf1IAoTbrtVwhqiCCiTwamfsMhWOdrQHO5HZHRVmkFTSFrIMqGs0I3A3nMiJVS0lr9RXU1PlYenT3t5/8IiHbzwz5TbLcQ+ZVhfHBhQawjaTNyI0H7cQk3pz1vOYMHP0smK4UMN4Mj1uhzbr1ES0jSHBAOtYSvOUcm+td4sVN5SUZ2qLPrwCFjaFJlovqf5+/VLvh+/ppaXf2xMQ38FCE917GrI9kBLjl06JZEt/HEzqgn1lDQ0UkT+42vssoEx3VgVcq/xeAdbtljhft1H0XqIFt1J/EVCxfpgV3HcmEWXA60Hc4HpTRLiwGfDp5mwABXdKQg9549xkXkL/H77xs3gqKpuAUSuhcCaYJy+KiRlk5E3Jx1q087nIT/yQuAPpczASwJfh5VbSW3+yUsKbbFEtsNzUn0L29/oKv2rmXJ53AZWNeP5VsKyC9u8olf65vUwQxkUg4kx346p5rftlbiUeUUzhXTerMj/ioKez81LBxvnCq7+IeGpTBF0O50Z/Hm7RGLyMoyM1pbjIC9HWQr/IQjajIwjVQA3P/n72MnM3pn2hZIjiEoVN9D3xos5yorzmPGSxieYSooJlwKPod5jDoxN/uUDLi5mev1HFKJ+YBhbzjOAOzYeg0vsMK3aMs9m1td3iLJqA41+cA5x+1lp0KmjkgxJZPXawwq8mokRrcXkck9/aHoTp7VKT0v1MwW6xe2Jmo9/OpbH+Tnnt6xZjHEzB/I45/nZZsgnPzCwXoc0Izj+Ebkgxn4yqFfSGuFMnvn63w1VLxyoP/Tl37ZSTnwr0XbHa+xcOgQcgzosh8XlJWWeZX16EEJ/G2+0sugfoBFfDM2VbvLoYeiBx3uwmpAyDSFporOlYd7CAZ2JyXtKFOguMzuwTuSCZZGII8PUcwyQLsKyvO8kjtxMf1usQwwuffV+M1uP8JINzXB6obmIwToV6+l6YZR5N2v83RpeXAovEIGVms4ukoGjaM9QfxjL6vBp6SpEg6ohA94LUVNpGHGLrSvph2vjtgWApISLrSF7nMQ+GhfgcHljbbjULdanao9RXaWf6C/bM6oelrfLV/tmvJCB2iMOPjQAv6gYynMR4mJ3ef+WZ5XLvz1SWCt4sfosdftkKFqJlq1NDHRlgia4jPjpbCPpM1nQ8FnRaa8Eg9g/AsYwVP4ExhZGRub04YhfeT7oOfvlOao1Z2o5BK71OyaXyP0vafLethtdVy9hIoQ9cpug34dq3jWvO2xttUUx0gvegE8wnz+lKUU/FBHGs+3jSmZ2t3pNoXHACjXobYID+DnOIh9iH3+GykQQe9I2rx60L3J5ES0w7LE2knTGZsdaQYiXaste+ostAZKgyUxDYvMNECqEnY+oM9r/F+1uVsPjQ3eph5Bxe0qNqRpdAjuHWdEyzdMtT/ow5/nAW+ko2G0uoimDoYU7ZF/hGbcqJuMSQRvCEw3HUJ4r3qJkqf6K3iT+946suzEdKK2cW4YGAfykUZroctfQH2Pmx0Goni0tphZi5cmKlOwkZqd8KhoXIBObNRlk8rxaD2JS83cy0yCeMOjte6aJ03cs8tw5XNChv++evElfS0nlKAt9oeI8Zi5z/dIedZRhOpkXkwGyt7F046PMBa1k8yxtP9vF8LqasjoH1k0bA1I89LJgAPjevlIhLIH1m/KGES6dt6DwAEY43BZ9gp5E+qyyLoKstv4L3ncbLa/Cw1FahwrbFUt8FmKKkYSlL8QiXLVQb5Wi3KaiEV2D8Lth6pgHnM5OK9S3k+RDvOzPfCSKdg7exc7KGp3sJnVR85q6ygTvUf/fmGRrXzruPn6x/AnE98MGD8+QaRtSY7b5qu7+N3j+yGEE//uAMf0cqp5rn5IbIiSYeGu1VF4YU04IMrkzz1NPylyB9KV7Amu2Ae02fmEvZAKZ7y5MC3yHVNhkyd503GFZg6v51tTT30xr47lTKvwoETMSXipaVlWNlJGY+WdZPUGxFqbAEmXTq96Q917vQ4WF1MSDpM5eNc1b7dXjFAx+wveExl40Mx+BYpV4qVQ1inK7odh3xwBfoGky6WVCeLLjZbbMPO+7qhedkEZ6Q+LezhmZc9O80fdJYuxjuPCPmVE4D8InPawRVfVHgv6xrpgX+q0O5u1YCZe1LbCxwYbN3VEaxxUypNU3j25Xa7jF+o72WJW4ZP0dcZwhEAipXKExO4aOY9f7czF5Z0H1G3TqnYAkxr9Tp5jxhcc4f+GBe79D6dbM1OcRH9nGwUtPJB0ffvKkuaqId496HTMr5zrIt3MzYua3W4yXp3WzcZtE93ng1+invbHIUIym97MoetGqE0aWlkmLIxLQV5kOnNYTXBVfCExogsHdCwrh3Ne5/p9NTLCMA9nXoPEInFqUuROPFqw1TcN4Ms0myV2mBhHp4lFQ2f/neRx6w7hJbQzG+hk4mnimzfFIZdUA1vdBnbf5aKksAqWv0rPMQzfB1PJU2h+Gzr1bMVzbiHNXqwRT5tegFzAU+/RabYGpEVCHBkPLkO0eSFId0WFe+fOCxrGBGPfSqJBc/w+xq0sfjrz0rKDlC7VljBOTVakgwxwuizUdHp25guihNzHvNAEz5LJJKnxDShVf4EhZS/ynugqo4Mgd0CsDnVwneZ5oPcnV+kpJVOBJn6iNWUW51VCwzTjln47HNv9EZHNdb50ORquziCJla0IyNKpu56vnaxthqWC50nzXkaZWuuANxbC21l4gUvwnZuY3UoZxu5B871Ysp2guaboV8y5Q8/UhrNzAvtTebv0f964AZuamLWHtP832vEgSmwoF9HBuy4hbnSjxXleYODb/xhwDGSWWtxiuzUU0VtrM1TrlptW2b+pD9luvxxC1aQ5dWNs7bqME1rFZGAD6ugiezL1AhESyb34II+Bk49U1zrgcsVj2Z87Jpk+YyNPnuuoYZ8oESNqAP8aeuTV/aiiMXEa2uCByfuZU1KSWm2ZNx0CR345r2AcTikU0Q9GL+Ol8uBF3ezLtkxoo/27UfvsSNxMqIRdotlAADDWQ8iG75W8onLJJnwvgOCuT4Ccz0/++Ii4TXTnp1+UkdPdjdB3QJ71F3Kk/zekCDA2VDAVN1knpvu+rGI+QeQXcrV9xxyNI5YLDfE0fW8uyttq2FSgVJIEyExK//U9+Zblu6nFj+IbtHeplOLm3v37Q3ezTFEiRqo7dpqCKUzb9aKjMffXFJJi/VzEFKnOe3NEVmFKytIwTBeyRt+xJ7PDZEKejDQ4L+y7Eh452Kh3HHbE37fonaZrJDS6lFJw/iBnKw7bI9CLneg7r4JGH3vbZtnH+hluRXgtK6HXZDe7EX9qdn+ttRuVLLEO/FBxmjjnbPmpVYf9CYCP0Vh0kuoFtixUqqS/UdQJ6SQ9hzyRS4hhbSsZwXAlDFf/OjUKbNcXv7rjiNWXkTsX1hgBRfx95A9L/3e8hpJcyouOH/sRva16JV4n3hwbjLYixWPHx2iGcgxUJkvhYk1E0kRe/8dzCmypjS3awFzc7FZ8Gb6czNx5oA3O8sLlcN8BLgjAsqHTAQDT6SpZB3ZdKsI1ytL3Himi7qHDsKwNOu2nGL4ywB4b6KmBeZBALf1AzzCCj/wrA1zBsD6oJdj4dgyC/Fz/kJ48iG6zsubIYp5STdCTS5x9bqo0i0IQc2z0PJNhtJUayx77jOR/UMdLXTXkJjVdo6/T5eSG4GFG51d2BrUBr4je2VF27+VMVj6kH/qJC1QXM7V4b9pVpDkF8FzOlAOz4A7/BZuBCiWzc2Zg6PtBN+z4pfepO4mE3gD919Hd99Vm1ojrFaaxP+IwpUNZGWrv86aFD1HHwYCfM9lixnkNlbA2ft5VnsIbSm4DDEIm2KMTmbaFMODbNyWZ12T7iQzQWUhOGTmty98UJw7nyTT80z0sNyzfcx/J6ecOhG7EIAElCF1Ogk5Bqmn/axNzpnkguQQqIMyLdRi8QfkxYEcyXp3+7HFa/JR5t8Wwtz/uvqlIvpuQKvrv7D6YT643zwCdKfGhBVYWy+PKBZysL5PSfj24YV60I2pRFv4MvnWzHE4QoDkZQAxsGrqoeBF/zrYiPZP9nIPFy223zqMDu2M2qoPCA65m/J2MVXveuz5cVat68kjB2uW/5PeoLxK3Q1gLpGZaqJ0L0ASztA2rWScXMkYONwPrgLUJQ9oUx0O6Cgir46QRTpNeVxOIczdQfpXWaVXtgp2UAu4LubqNOTrPQhVUq9Ryy+3Y33yntotv9B/YJfUgBX1fL4tYJlE07vdZ40fyR6M14zzUTSpKGnzAgZIxM4DJ4oTEul5WMRcVwTzHW+AAAAAAAAAA=\" width=\"780\" height=\"114\" class=\"img_ev3q\"></p>\n<p>The problem? open loop systems can be inaccurate and unreliable. More importantly, because there is no feedback mechanism to correct inputs as the controller (leadership) never gets the information that comes out of the system (team engagement).</p>\n<p>The key word here is feedback. An office hour session is great, but it’s a poor “sensor device”. The reason being that you are opening the door for the team to communicate with you, but that data isn’t significant to extrapolate through the whole team.</p>\n<p>We needed feedback. We needed to have a closed-loop system instead of an open one. By that I mean:</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"data:image/webp;base64,UklGRvIiAABXRUJQVlA4IOYiAABQoQCdASoJAwgBPjEYi0QiIaERGUTYIAMEtLd8GrRS+kcAlz/eE/gFVZ+M3O300hhozW82esUpPxf/gvxV7/v7T/bP1z/s3/d9efxD5J+n/0j9f/7H/5v9D7tH+T4o+EPMn+WfRT7Z+qn+M/tn7d+/f+5/VP/Ef2v9nuYL/Lf4P/av1j/wv9o/bL2P/7r9Vf855gNUPQX9nvgv+I/w/9M/039o/cz1UP6b8s/IB7Av86/gn+M/VD/Y/3z/+f9L4Ku2T7An9H/hX+p/0/9J/5P+F////x/Gj8M/6n+//oH/x/1HoR+wz/N/4J/r/9L/O/+l/iv///9fsN//X/P7Jr9B//5/3RgLQtlVYB9vACSFISWhbKqwD7eAEkKQktC2VVgHyLzTxhq21zNkqJubR7eAEkKQktC2VVgH28AJIUhJaFrbdtaQZRvh/1oicb7s/gEtDa8904q3BIWwvpkrdNNjwhyKJOP1OJx3ulxhVQF9ORr7L/joHvrUffT6j4m3sG4q5gpCS0LWnemY7rFIFYnvitU2AoPxsJUYrnnLuKZ9ysEzfqp6nZ3hyYbzkwYJEd8hn3gZ/ZGs8mROEpydVP7wQBfiV2OsQhVhbZ2JKjboBOQTqKVkFsaiKiQRyoMd3eoG38QJ8Ym4HkC1y1L9d6H1xhYg81sdboadvahdWg8XImKsfJSimF99u1KHQB43XyvVrVf9d8oiP3xOWuPn/rx6vL1N9gRe5SjGuk+ZGAFu3bwPNYkt12SNu0FnaWN7Uzutqr0Jejb5tVYd3W+kJq0Sg3LE6rhJUwB+OAeMd7uAYa5+aBeVhtGP6MkAJG9UAV/4Pj2oqeA4JKM37ljavFDX656D8MugY0jDWyp2s0RmnH0ya4aLekdg9I1OX2e52bXd+qXENkgN/vA+bo6M9TZooHA7q/tuR6ybpfii2iBRDBsU4PQFnR1XgaCIKHG7j/MIUU8tu+Bheur/dbmGe5/syvtrkFDw3VlANslb1fITq6LKDdPSzCqQoXXGqB4wIIxY4BFeL7vTgYzMG/S9ToZdAhzDze2AVhU2mbRfh2aa+t+PAPSjVWAfbwAkJnxkiCBONYpCUggv12AfbwHKQpCUfUawQaFsqrAPt4AOpTV2qW8AJIUhJaFsqrAPt32XuGbAfbwAkhJDqA8AJIUhJaFsqrAPt4AR/7BxGwH28AJIUhGcGeK3VS3gBJCkJLQtlVYB9uq+PjY7SQpCS0LZVS4n5Vj5QktC2VVgH28AJIUhJZNzybEVYB9vACSFIHpgPV57T+jACSFISWhbKqwD7eAEgRinChSEloWyqsA+OPf5aJzWC84WVVf4dhDzCNCTKBT7HNtR86omh/CmTxJn0InE2L5E7wAdRECWfRp8nAfbwAkhSEkyN4zMn3GyYneM5vlfCghdqebf1HsNelFmA0ykusGhmKWXcX9SHb3SakAwtnD1fmwebpQBhkG3yMmIB6g+xQWm9BCQ9jciuPflDyu9BJCkJLQtlVYB9q7LzApIl9hSO6kThjycT93OT1Cz+3VTK6WKtZjJGB9Bae+Vb5MnhBHNxDNIlNTZdvkyghePVgn50J52FGnumHv1HwpDavo6Y0fTWy8EGNIkc9SOmeX1lJXzsHGNAqrAPt4ASQpCS0LZVV/kYCaOPN8Ddii78XohGpe5s5XdYOsknFtBfDCz5IFn+AEkKQktC2VVgH28AJIUhJaFsqrAPt4ASQpCS0LZUgAA/v/NBYAL4wDj9bBO2wrONYyQKxkVWfgGpiq5PIp9xdVGbeMn5lSDMkV/KW1zV0qj6Q7O5Ngv4B5jc5KOO0oklZHXqLNj803Fqln+jFa4SUW437RW7yRpk0GGtMyH9jhHyJ92uuMTXZinA7oQk7qDf0eZ/Y4rG3h+bQYl8TndLpiRm7oF4uvMHNda65katQI31/46eb3dnzJcJxR+d8GHwBxNWuV18X9APH+Cz3cK8bLNcJBGP4KB1nD0Eqkv6mffDtU0nzohdep8L2OZN2AAObaZap7g1+1+0hRTP7o5rAICisGGDa/b7n7gN/Z3AmjD0lNZnv26tCf6aWfiJJt5EOzQQXd9NTdwZ8pwCmEU48Nftl6d8AiqbmIuJI8qBpTxbsLTtwtuj0uNuYw2EoNRNb/pWN0q7+K8CZM0S2mO2JaQ3ZHzKDBuzYRR++5H+VWNTnseSDmuNue3srgd2ySWwo72Q4RZ635kRkov0HUp8ZoVMjrbbFEx57OnvI7MUiiPEMYNgiNyIXITmVYaqkSO+6//XO8lpzjanFTEdOwoBlgWZudjx+k7XZuoYnCI+5q6xcgUxcWxAe+IcuWg5Nv+6hEPg0owqahKmNW5BVQQtbOCebCzTg12J+HBmRJ+SwSoWAmgpxqwf/yIJR3Mg9yywLDz8wgYV7FMthyLLg0sN4tAKyOcNZXSmBBJ0mKItZd0FOkUnQP6Pgkw6u2YmpcqqwgsQmkli1ON4kYOXHZ4Zq76HhQMTmo/cfXJJlrHQieBGWTboSj9OzH2puumJDhNC00f+lNsCsb5T3Hm9TcEu3EAuBP0e2QnbHMtUGBvNTY4UcJKfnmNP3R19ErUERxl5+CuQRrTEbtLnByVz2Qwms8rTFPehRbc9lG42YUGlXZJQr1D9UWK6PaP3kiSOCrxhR/lpqg/eN0D/xjGelHZdnNd0CtynG777ZqFdRLKP7taDZT0LxRSB6mCk1lJY8DT3iTLMYp+diKgDGCBKt4822YaiGDlK21WqzhrUt4qz5sRkICz7kj0loGEBM0UnrEvB17wCDxhH43kaGYEY7PqN/hoKVTesC0FLyYXqqdeR4qkXmOIwd8jM7UIXbGi8rCGpGtN/V6Wzo7rf7UkmWHvOcg/2MCCY/rJ+reyRQc5giY4eE2Umx6cH9uzFdioI+qH6F/I45Zx6IGrv4E2B6cdJRMEGWdEvDt/iU1Sk/vbbezJPsRGbKx4wIyBXAhyQVzBg5YZOzvOXaeM5wdZELItw4g8XfrPHaQaui7UaY/ioNVdYOILV4C4Ywagq0aRr+Dp6cXgWeJRHwv9RMLe0W6oiNpLcD/mA+TwQY9E/Ejx5M65F+0TItcuZbknKTLuKDBvY6sm6JcWgNO0AqXRBss+fI5kQYdwPZvDU/Z73suU3ae+q6AMSLYO4vmAuFQOBDYYYS+ZfC5sZWI78pwLlo3IvFRkE4PScMBQJqkTZ0mZboEZp6uVqG88tEjD+H/CHapT0fGNa0kaY6QlsPjYX6K0dZRvJlhLA5AoAk6tpaZ+p04RVOkGt4d+5U8y1c+174fjNdTCHC4W6b5F23vDLoOGletE0r3VuHJvjsbKMuNMsyi6WzHkWv2I2aNURbe6L+YA1qaC7UHvLPSbeKAWtjHMSz/8bBlV1sMotbFM2QjaFRo/dAQKsk5iWwX9Z9toAdHZloLbSujaba3TvWWijVr/0YdaFbbpPnLzF6hQK7qgsDuptbszkfc40+dUp6Q/SWr7gkMyJTkmYgkUh0Ng+72QBq89kN+4SIGk80eFgDE7hJOYF1xwGAcv9Fx4nBxgP0kvqJHMuiq9UfMhRHt6i1afEOMlFcpHk+p/OsCnF0Q3LQxcjjOEoBxSy/yLd3sK6yN2DL71a8wVpfbXDCWUrHS9FO339lOQftznE8lb3BtiOJAhyjvUe1Oripd6RUAX4cK40ZMpgFvhjQL+k3CDGjAvs3pAl2RlPwskOuMKt9aRuNHWhMJ0WpcraftSF68g2EY7rRXWyVEv0Y9TsPiYbH/1PEfyX1krJ0PtjNhRlwovrepiAQ5sKHcqpEPz8Hour8t1WMXzntWrD4Tvky/xtSkpvNGGs2/ABB1DdDrnR3D5GGcBXAbN73ivv/CSHaEZpUOJPmi/bl+MFdJCyGVM0XvmA8o8jgMKffXxdzMJDNQ+Mx3Ap1VtPCeJhdEGnDAP8NANA1bsFaBpeh/i9K7ObIQl0lI29ZflbMQEF6yp+V+cEtu+ux9psnDeAmFW+bVBCdFSu5gqL7vtOpQG02+S4ikOHjkZBS20X/adoAqpuY7FENUgfVSxVLLrdS0zrElG6Beh95unOm01pDFxBjg7Rqstfsq2tiALHQlm/yKvHk6h9swlXzB45/Y2GpOQpzSFWUCp+YdEKjYme/xOE7cn6JzGMPUpfhE3PY+k+rJnLrBcOUvpL6/9h8zrS0mcOR4srhytOGmb3PJ36PhquBzuTLrvhNQSkrG7uwTLsR6HtKZZ20bsc+TDdahXih4e2BK4Wl2/PAmWEwPf/ShFHNqC0z1NwdFoYeVn2lsXkcWSrCphV9DYVHTVkEV+JDJrlkHOku0o9dq9EU1MKCh8NGPf9GZ/afbC/RPdSxks203ognFImVnc8ze8w8mF0/Mwns7ZuiXtmAPcGSk22koBRzn6YLLum210m3HgPbsS2ZA9jgArZsSQg8XzA/3h2YRM3iInIfLe5mlq9CG++uA9mJidSG+K85nS/2UeMxe5/uQolMJAVxtMUTAo3qCMx5p96fizQWkfmVDrIOogcC2rR8TwkDjxdAHGxEHGbB4JP44cxtBLcJcPHLq9FksRmglFPNjtaKqtXmZhVXyJDubybsFe17FAb9cti86Qz0DJT/fwX08zCZYqlzq3G8IioQQvK/UPJPYEYceplX7efNk06Szev8q2nTO9OPtOBT8EeOIEQQHd4vQHfSKHj2CX6gV/Ad87jfPnMyMlJIlH6NbeYyznSoRUaLOGXrm9r5sXjAF3bXFCx89F4L72HEvYQfqUXZkJwsetSmgrrgDkqoiglBMiNT/lqe+yWPNp5FE/59m2xcmw9/mVPA5nNFxcQVWfA409Hj59d/YPUemNOcr4tCfgBSQIqcSkI3C34BZR2MKILr+ghd4ubWcYhCkU8QsGiXOxyGSKjvIlg9ng95OfKiy+bvhoe4R0cihf+5QzgYnVztCeF7jN6NprFD/FK4H92KwEvhTfwirwpf/1TAJ7/QrT9acCdp+xuWVHjat63F6//Xm502Lfe4MOaEUYrrsQq+cPHgs3v8WgId/wTJnHsbWckvNdqur0hOQwaePFH6Dq0T/EAginoboz98o2uN7xwa/+uvYwzliS3ORtquF3avN117juPxTK95wG2WJvwOzzlC+mGjVpMCBEIMd4t1T9AmoohHTiLMVRBn4OEtZDLT6Tz9IgFS33HDzSCERmoe3LjfdGjNDhVxIvE06u5+0qxX546dYJi0DmQrlZxq5sOT/e7KLYpynOz/qs5ibJ2+lFnwPNeBZFfOjTHvpXGRCYYR/gsWaomkYKJK560VeureSi7Jdpp8+qj89anhDAjNOHuBZ8DMWvAsewwJEKYDTdU57zUVWfgT34MZgU10I23sTSaOlD4AtzE45VKAhWiMrHmONS+XR8jGSt55lkxtnYDMM8G+IXsS951+vDz8wtZSAonyI/ifIu3neriO81xTYUhSIhX8xyVqka9Sa4kns/UQhqKlQrxRwdeR9gLiWlpqsOhgzKTVwgRU9L0P9bXD857m5lG7RsI6SmbFQwWf2NPjEqREuS/Qu5BuwMQ60QllaS8DKPALVzxo3sAgEKS3L16QNnyYJ+xGz/zjWOMWUql3HTVghgdnpp4c1DeAXhPfgPUA1Yzy57u/NACr4IMndphi8707FKxI0Dzws+y9JirGfcf/4Rwf8PdUifWDikEPlHR3IUoDm6A/RVoB4FO07ggCsoWiMIOFUwdNi2C1CCZj6HvQValICVgpQYB2Gr75LqnLZ5OMcwPP+XhCnapTni5tIg2UHscoyWCDw7GiXAl1NBOh+JtwhF5PjKObKVeaw7ycYPWXTFB+avOJTPDaFYt3d5cXMqZrGEELUDj38BVjJQFPE5KNzKcWx7IwotVUB/jEa31H38/0cbqH5YSojSu/4c7RESCFKytHpT5pfPS2VENQqceVD4mbqorUK+H5UhO6+QjsN2XzmPUzG6md82q9FFpg4RaN8ouzdz8Qs31OdrFBL/idlsXT1M7qJJGbKEcm2WNgrYWJN3/WdVe1uV8PWwsfP+xTlStEZYg2rw1JhxTI0dYyuTZH9p7ln4jSLXKjpYHEOG+1270sPyM2ytaZsmwq53dbJmpKeuSQUnm4w6hI0+aJ/3cdpthDjae9UGunPzEApNm8mI0aKaHN02Z4jiQ7GXFP6hrmWix8K58R3KCYEKo42mJozyjj9G9xdbgBXcwfyQe0EQRAPYCGs7T/SA1WpBGoKydooSNBL23F6r86H/xzAbvkWIO44/6VRAypUvEbSm1Gj0uFsxVFjkFLuqWapV3O/X0KOk/fK60A1s1E8Bd+VxGnDIceVeAEoXj8Y+rAwSQyW2vt8iyfAKcsG1ASqs1YF15aQ1GzHMJiJltf3bKfWjr4O1rP76YrKriXhkd2wNy+udNoP7Y5WtMk8pmeXK+dN7c0ZfG5QFysSQImXZNyaLgRLSSEJNYV4xsWoQj9pVBHtTUyyXdhemeTs5nx93Sqoi/lH9sxSNu/PEhC2frZ0zyKA9uKp8VB7QTBXKXWM4u/exmEfZwwA0OyTtfOVf47I7EFQMR+mTdyHgeEhQmu2klFwcgL4YNBimkHxinfMPSH2rRFYNrKVmvcVeDKVu3btdPIdvaP/Fp+C2YNQxFANRSWvrjmPX91oOik3GyX44Qg87PpyrTUM7Jj0nfIEE0C8mfGJhqHWC4/3QdEPNDHtxQ2CkUiqGDAhJrYoJEm/azyQbf/cUwmrcjSAsV4ghAlIiKzx9Ryw200T91q50iBu35Ld4r80FlR0topm/sY1rvyStTmzJwMcRNwWdyv2cbh6iJ0rfhfgdCaOJed+MRPB8d4nKO0m+AYlM+zGyjfgyyQRjb5VrtDH6w0F2ZvIz0pDc62s698R76gdhEnRn7a1++HZTg5ozDXPaYkufuDBsb5FBVcx+65H5TdDFAKYDK/WMuAUXJV37MwtuliPWGp6YIwXRGM4OzS4x9Jh2S/gWp0x9m4ekgVoKopoR2DwH/lxcfs4LZXDsLNPgfBkRilDJAwTSnHfr4kYSqIXHodIYgznbRDAwvf0dfPb6yW6bSgN7qJw3ZnQvjxFej/Oq/lTrPkKaz6NBlcQn7AZ026ydhhAlhAm3fZPgbVRf8f/DS8eRzXkVVXw56j/yuX5AL/tjNXQc8XW6XPOqRowD4jStZysbbR6FLFTc3bx4V9/Vbf+tRW1mgjAszgS9nkOwX3uOxAA+yGtmcaPhKwHVpJCI/WVWueReyeNIC6p8PkBySY5VNQnRJdsnf/yfJ208myrMMcJNnBaaaD31CLa0zrr3/lrhTjoOkIxeDGCVPBB/sLCyy+D7s+9t/7AjBKoUe6sOsicCY3fxuaahMPGYflj8BoJOswbY8vZwZIYR9pmM7qB2vJjWyD7NdKdQJX34qnO9eyjNPgkRYQPO1uN5ZlyAJHNKVIKrXAP7QgBbfZYGNSjuL6p9vX/ZtlywaEuvrJyENLcSjU9NBvR9yxdxtys2rX0pTCY2j9s/XArYzetqinerh96mfKmcsI3MoKVZK4FAZ4zaYi5oMbukG1MwXRzOK40QwAzClILlRFmI72UwoprdO7lu/dnp4Vd2fENXVF9Dll5nEkD/DPiL6T4kOPluqepyv5RQQIhNcl4TIG5LgOC7HXITeu04A23Ywh1gkxiMErUViVNnr3kwGx9vJDWMNBiMHLWFqTtEivbmAM5/bUjAQqR3KgQEHbY0ME7HrLz5bEh5aW3rTMVleh7YZVz/MUFn36K+K3vtG31wZ31srn/4eEcG4JvqShPC7zQWctpdQA/nUxxgQ4W9nLWUYOipo1E3PLAof3Bdmf7QGwD6OPBvhFA+jOb7wgcYCcYlzrAStrHGOr3tkIPwgA21djodNfc3MCtVm9PMzdzVRH8B+ug91Z8Ylj/Cd2BXXuwnbY7d9R857sbYWVk/QKII0+ayO0gqyx28/Vepv+JaWlWZRf05ADqPvTnqfJxCwvrEcSYOnHZxG1BP9pp/Wpj/6cWSY6Pry1XFvZ81zRfZr+9pWkVGzCN1sveoHPZeTCdC1aRl2CKSND6bSw9tYWHk8Cea9bdjIJFHPgIPGLewjlejgw1OS6jJyYeXd6bjQZPKx84qY84yX3QKHaQbDFSrAVd2Gm+Ax1Wp0aAM5uLKRMk6sj6sNx+o+OgAQDAdoVW17DgKmq6giRzxE1RLE6WVpT0VuIufak2Mj3TKJQgf8bIuSZlXn5+ZEBmDhKri6rt+3wDXE9Hm9Hj+qeRJ1Eod2RlB/X2/qvjej4xeF4YJC/fAAzLCScM1L6/z+rQ72uYwVXQ79yInDxy0GQWId+Vk57cuEX33ykGwKYvaEjKNVmOe2MqpXEGTMQU8khDssA7V3caixAaqn4GGFmnrrLUnAtBvAZA6C21lVT482+z9zBhRpEsLZrZywkIEo0pbupIWk0sOxYjSi6YwEAAAAAAatn1JLp0OrMn7iUVWsACgd5UEYuXQg6uOWKy8QyaGCOjp3HVMY6PD4wS9M6figL/1IqlYtofoT0x+TnoT0x+f3ywOq2Hw+DMIamTCNxfQByAT+OqaTcgLX1liwT4mrEyX4ReHNFG8yvMBgsxDBnG2OsvX7g96cbioAYQQG2eUdMzaQbpxOjJEWZMppCwkSmu8Sg+cb6iOrFA1zJvoXfIBb9clrmeDi2MDuprgzTT8lqUcM7PDdGtTMyus3OiywYlBg+zv8cb5ignfrgEF7yl1x/7wuntMwOkf++euXY9fbUW4cycEggjwbnaJmCwcCnHMHgzOFDp8O/BnfL4/ZyWz2nFE0uuLeCzUupW7d/lF26d89oQ//sn3414NoYjAFgxoSF+GHTWlrkWgoQvhIGrxulGGT6Kyon0dcn7EiOw97gi6+O86/W8Y/XCeSaAhdUs5Bbnuc7IMC4RjO4CiNfECtqueKF+udPaGf5TgB6bmuj57Eu0Eps51LyBdXffv3sfvqQH70rHBnbsdVmfCFIp1bFkpzoR1Pb4buDjPsQrmemuD808sesU9wWTWvru86p/FyUBd9u/fZwiwRMmmnsWfs7mYGABtSlps0mV1EWBPxtonxVpmjkTr1jPuK9DZ6sTuq7K7K7Ku3nu5LN7htJ9+Ob+zWWqQyYr/8FN9NBeaaQe6yaEc6mPrdxC04Hvtdhm7gbVUajXPDSPZC0fYrJCY8clikN6yH7CLD1N9NgR+h0VvyP41TKxQ2kdLseV3nh1jHSuJ+w7g045Om3oN/wQt6IgMUIDlQx3Zw1pg/XubO5LPO+0mSz+Y+/dtbDTH16fKjjUqXJyefLyn4emeFDshLsyUcoaOAFW8FXVzfl4DeybfAqsrv3g6pHiump3zJQwftraEY9meNsk1I9huF+/yY/QH+P2mbvM2AIMaq9mhe5VFjQLjPN8S9wDXyYbdoShfYWZG87xBTkG4HQ3s8t4+foll83TTwZ5XGeBMryjD+UzK0Ym7nPKD8WZkicScT8Z1nw97gfIoYDpRJARz6ffNSMBwMVj8OfpEF7LUaMujOw3JqZg7ke88tEjD+L6t3F6IpUTm1lh55SYRp7TIdmv0SW3W7cD4DMkRATmG8v7va+70rRaz/kuI2AjzDctYuioMXqczUIL6TbI78SizHaHdwxDDhvE5/eWxkWbAMHorzshCl2Z+iEsT1sv6f95ogVb8I1T5jKj6Y+jUkwpy2/TnqavN6UKEu4kk4XXkzPn2posFfNBQ2eHRSuXhoqBmGwxxGxCPMJ+oXAa/1v8MNvvYZZO55y3VG0Oo/j6qpnLCoK/KnguhHyVsbGKLEll1VVB1/gDP1Z1kZdkNyTP8StZtm3o/n61woJA+8FU7xqOvXc7v12aTsdPBu2sQcg4rz1pBa8Dl+3Bs3gne8Q9O7/6GCkhf2YowI5P/npRQiWmm8bzm4PCMfcsKyCXT6AHGf/28yyfwQovI1cr0u9WpIoCET4ZXeF0V/5r442eFQ0tiDUYtI/XOVIsf0+3uHlMF230tJ18tCQf/HRLRT5M06oTBkzyTFPAnAE+GPw0uoJLu284ezd0DEdjDSSps3AmP98kvZOYIhWyE8MbUmvI7ktmnhCy+yVvgMKwBqrjP0b3OdA38ab4ZZuBHLSt/C2UIl5T+Y9LmF8mnoZN6uggBWX6/sI5bbdIWw9lxeI2zM1yZYg8yTo/X6yoV5uZLbzVJFcjjD+SPzKpZ0cFkJGS/GFJ9OTfJLHM4WVmzAflJ8bSZxVBla/WIfRVW5QUORIgs5jFLNi//e2mjobpgexqoUEKOLwxkKi84HulZg1AMZjiqfpLqpOUJOeEy4KSnT48PNHkYhL6FV+Al4AFXruXO4246C94mgAYSGbI9P0tJ0W9hoI4UHYXSBrDASIekdlVea2FOoY5g7asfxYdRCJ8HYXQbl5ug1ymEt7+DSS12kYKuqTaJGjCRowKUbzOwtuJ826erZRru5VDcEPBmM3s/3buHlPNtvzp0tdnOSlVOCNNGeZJRKc6i0qA7TpdPF15CTOrPBAuAPPsda+u1DMnfuGSCVJm9utWMqqORCYyGnK3DzqtK5avvPwDMOPViTzezL9na3GfqZza8uJp5wRmq/VajsRZYyTTe02fWpgsfVM4rSEIqGZdGLSvixcG7xhs/8mOCEduEu7+cqKnvfUMP3p4ZxLGYIIjPofgTtX9tpjS13UjR+C7Z32m8Vy8ktAjtMpeCVMcYNz5MgpStII0l9AU3anjEsylAyM/RakcKwULNAGRX7SwsWdlXBtxIWwbbsE01PWrlHyHTg8fZLF2y2TxO5w5dI7Yvw8UGwXEMYMtRgWxckPcOJvP0qhRzFr1n2e5H0jvT5gkLFQPkwGJ9H/VtkRGp7ngmJJsGm3DNEb1n5wkoiFFaqFgPNQBWCUxi0JtGwE05XNJswkQ9wOzFz6IG68delVVYGivtRA/fKt+FJKwLkTbn+Uqu0MGRIv/18sF0Ds4dyccBGrZG5HXPyXeEwFEAijaKPypaZRmfSE53u19TZBBPvnWxWu/0enM63A3rNsHNFpZWEidbAWBe3Jcp3yQek2bxopEZYsiKZa3jk4FerqV1XwaXkuhB9ro/4hzklKGAv5QfgcLvS0UMfslJ+4k1bAksr5E0shnGO3tti00NanaG5jitN/yCWJr/tUmJcB1WaC5lhbPTMzM5csVfMHEvEWB5705CcyutSVUFNVPGcoYFTj8cFMjkA2BZBv+l3IvCh/R1N9KLa/X+ayeaOpJx866094/DhFe0vLJ2hB90IPLPzHRWX2tohbs+K1tY3uENUHyl88vEmKK+t3qf2AEWre5gbW+cIEZDldmaeNLplNTXgwyiikDHZetjNaxi3HTsZi+myYrt9kcHxvDoM3NxKD9+xFcHOjf03KZ7BqL0qFz6OlUsWZrA0tDvrF7TTTSAleJ3Bv2iwI//HyK9R/GWppQyu40Tb6uO9unmYkaqUgv/zexpzR6HXagWY/AclNTSyUGhj8/Q9EBlCZwWPjxGLlb7+gDXzal4Z+PcUMr4zw+q1Uj5asKQZAFIaZmSookpawX+lB/fvYUBlHB8C/ewIVh4UipIUN51kRde7PfG9+LMUjfEw1nCZ2iHF2T3rn9oC7p+68/ah/F1uEXugJKYu0lzl2Wb0pVr8MiUL9lFIiztgxBNdQyqDFkQjHgoyQAGFkqMTy04a7WpdyXmpA7YIMar8hip8G1EUcrUdDpSMBKsrIeJ8Eb+9axSMCB8+BW0T8co/5B3F/0sib0pclGIJVjhXwe67tw28FKlw1giOUXJQYK9lBeXQyIDD9tBAafrE7Xt48I5Qw+RF2Ca1CRXddArsc2u6fXpk8iSvq3Eqk6YW9UWLmBZqCRzu1ZJTlCA1+wJ/FUOJu8FHc+E+KPXhFHU9to8/b2B55QGxuFdGza0TCpt44DvtTPcemxvRWqIBmFBcwz31N1TVWYAAAAAAAA=\" width=\"777\" height=\"264\" class=\"img_ev3q\"></p>\n<p>This allows us to constantly monitor our team happiness, and be able to react when the feedback doesn’t match our desired culture.</p>\n<p>But what is this feedback? What do we want to track? We didn’t want to reinvent the wheel, so we looked up to how the best companies do it. In particular, we studied “The Psychology of Employee Engagement” e-book from Workday written by Phillip Chambers.</p>\n<p>This allowed us to come up with the following survey, where the team would reply anonymously to each of the questions with a rating from 1 to 10 where 1 corresponds to “strongly disagree” and 10 corresponds to “strongly agree”.</p>\n<ul>\n<li><strong>Accomplishment:</strong> I feel a regular sense of accomplishment</li>\n<li><strong>Autonomy:</strong> I feel that I am given autonomy in the way I complete my tasks</li>\n<li><strong>Meetings:</strong> I feel that I have a good amount of meetings every week. (this question was originally about environment, but due to our remote nature we felt that the amount of meetings was something more important to measure)</li>\n<li><strong>Freedom of Opinions:</strong> I feel that I have a voice in the company and my opinion matters</li>\n<li><strong>Goal Setting:</strong> I feel that both my goals and expectations are set clearly</li>\n<li><strong>Growth:</strong> I feel that I have opportunities to grow professionally</li>\n<li><strong>Management Support:</strong> I feel that my manager cares for me and empowers me</li>\n<li><strong>Meaningful Work:</strong> I feel that my work matters</li>\n<li><strong>Organizational Fit:</strong> I feel like the company values align with mine and we share the same goal</li>\n<li><strong>Peer relationships:</strong> I feel connected with my colleagues and that I can be myself with them</li>\n<li><strong>Recognition:</strong> I feel like I get recognized for my contributions</li>\n<li><strong>Reward:</strong> I feel like I am rewarded fairly for my work</li>\n<li><strong>Strategy:</strong> I feel like the company strategy is being communicated effectively</li>\n<li><strong>Workload:</strong> I feel like I can manage my workload efficiently</li>\n</ul>\n<p>Now you may be wondering how we made this survey completely automated, the workflow is actually very straightforward and we were able to automate it. Here is what it looks like: Airtable + Slack ✅</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2023-06-29-employees-are-leaving-be-proactive-about-employee-feedback_3-440b201d561b82d70744ec0367f821d7.webp\" width=\"777\" height=\"348\" class=\"img_ev3q\"></p>\n<p>Even though our salaries don’t compete with the MAMAAs of this world, we believe that: our mission, our innovative products and unique culture are what makes us OpenBB. And why we can retain our talent.</p>\n<p>You can find our employee engagement index at: <a href=\"https://openbb.co/company/open/team\" target=\"_blank\" rel=\"noopener noreferrer\">https://openbb.co/company/open/team</a></p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/employees-are-leaving-be-proactive-about-employee-feedback",
            "title": "Employees are leaving? Be proactive about employee feedback",
            "summary": "Employees are leaving? Be proactive about employee feedback. This blogpost discusses the importance of employee feedback and how we at OpenBB are ensuring high employee engagement through a periodic feedback survey.",
            "date_modified": "2023-06-29T00:00:00.000Z",
            "tags": [
                "employee-engagement",
                "feedback",
                "work-culture",
                "remote-work",
                "team-happiness"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/hybrid-work-sucks-its-worse-than-remote-and-office",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2023-06-12-hybrid-work-sucks-its-worse-than-remote-and-office.webp\"></p>\n<br>\n<p>Hybrid work, a combination of remote and office work, is not as beneficial as it seems. This blog post discusses the pros and cons of remote and office work, and why hybrid work might not be the best solution.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>This is my hot take for 2023, but bear with me.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"context\">Context<a href=\"https://didierlopes.com/blog/hybrid-work-sucks-its-worse-than-remote-and-office#context\" class=\"hash-link\" aria-label=\"Direct link to Context\" title=\"Direct link to Context\">​</a></h2>\n<p>Everyone on Twitter has been actively discussing that “Remote work failed”, e.g. <a href=\"https://twitter.com/DavidSacks/status/1663958149437743105?s=20\" target=\"_blank\" rel=\"noopener noreferrer\">this tweet</a> from David Sacks where he refers to <a href=\"https://flocrivello.com/changing-my-mind-on-remote-about-being-in-san-francisco/\" target=\"_blank\" rel=\"noopener noreferrer\">this blogpost</a>, or <a href=\"https://twitter.com/paulg/status/1667580108247277570?s=20\" target=\"_blank\" rel=\"noopener noreferrer\">this tweet</a> from Paul Graham.</p>\n<p>While I’m not going to pose as an expert on the topic, I feel like I’ve experienced enough to have an opinion. My career so far has been:</p>\n<ul>\n<li>1 year of office work for a public company</li>\n<li>1 year of remote work for a startup, plus a few months of hybrid work for the same startup</li>\n<li>2 years of growing <a href=\"https://openbb.co/\" target=\"_blank\" rel=\"noopener noreferrer\">OpenBB</a> from 1 to 20 people, all fully remote.</li>\n</ul>\n<p>Let me first go over the advantages and disadvantages of remote and office work, so that I can focus this blog post on <strong>why hybrid sucks</strong>.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"remote-work\">Remote work<a href=\"https://didierlopes.com/blog/hybrid-work-sucks-its-worse-than-remote-and-office#remote-work\" class=\"hash-link\" aria-label=\"Direct link to Remote work\" title=\"Direct link to Remote work\">​</a></h2>\n<p>First of all, let’s be pragmatic — remote works. (Before people comment, of course if you’re a factory worker or similar, this doesn’t apply).</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"advantages\">Advantages<a href=\"https://didierlopes.com/blog/hybrid-work-sucks-its-worse-than-remote-and-office#advantages\" class=\"hash-link\" aria-label=\"Direct link to Advantages\" title=\"Direct link to Advantages\">​</a></h3>\n<ol><li><strong>Increased employee retention and satisfaction:</strong> Remote work is seen as a desirable perk, improving job satisfaction and retention rates. You can check OpenBB team engagement <a href=\"https://openbb.co/company/open/team\">here</a>.</li><li><strong>Expanded talent pool:</strong> It allows hiring from a global talent pool, resulting in a more diverse and skilled workforce, particularly in open source, where contributors come from all over the world.</li><li><strong>Increased flexibility:</strong> Remote work offers employees more control over their schedules, leading to better work-life balance.</li><li><strong>Improved productivity:</strong> There are fewer distractions and interruptions, which leads to increased productivity.</li><li><strong>No commuting:</strong> Remote work eliminates the need to travel to the office, saving time, money, and energy.</li><li><strong>Cost savings:</strong> It reduces expenses for both employees and employers, such as commuting and office-related costs.</li></ol>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"disadvantages\">Disadvantages<a href=\"https://didierlopes.com/blog/hybrid-work-sucks-its-worse-than-remote-and-office#disadvantages\" class=\"hash-link\" aria-label=\"Direct link to Disadvantages\" title=\"Direct link to Disadvantages\">​</a></h3>\n<ol><li><strong>Limited face-to-face interaction:</strong> Remote work reduces in-person collaboration and social connections among colleagues.</li><li><strong>Communication challenges:</strong> Reliance on digital tools may lead to misunderstandings or misinterpretations. There may also be technical issues or connectivity problems.</li><li><strong>Blurred work-life boundaries:</strong> Clear separation between work and personal life becomes challenging.</li><li><strong>Potential distractions:</strong> Remote work environments expose individuals to various distractions.</li><li><strong>Challenges with collaboration:</strong> Coordinating tasks and scheduling can be more difficult remotely.</li><li><strong>Reduced visibility and career advancement opportunities:</strong> Remote workers may have limited visibility and access to career growth.</li></ol>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"conclusion\">Conclusion<a href=\"https://didierlopes.com/blog/hybrid-work-sucks-its-worse-than-remote-and-office#conclusion\" class=\"hash-link\" aria-label=\"Direct link to Conclusion\" title=\"Direct link to Conclusion\">​</a></h3>\n<p>Remote works. It’s not for everyone, but it works. It works particularly well when the company culture is built around it. For it to work exceptionally well, it boils down to two main arguments:</p>\n<ol><li><strong>A strong leadership is necessary to keep the team aligned, motivated, and to create the company’s culture</strong>. This helps mainly with the limited face-to-face interaction, challenges with collaboration, and reduced visibility and career advancement opportunities.</li><li><strong>Do not track team members based on time but assess work based on output. Use meritocracy to reward the best team members and let go of low performers early</strong>. Remote work is not for everyone, and for those who cannot produce output/value to the company while working remotely, it means they weren’t a good hire in the first place. In my personal opinion, the disadvantages of potential distractions and blurred work-life boundaries come down to the employee and their relationship with remote work, instead of the company.</li></ol>\n<br>\n<p>Sometimes someone may not be producing as much value as expected, for one reason or another. <em>When you are working remotely, you accept that you will add value to the company, and time is no longer a measure. Thus, the emphasis on output/value becomes much stronger.</em></p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"office-work\">Office Work<a href=\"https://didierlopes.com/blog/hybrid-work-sucks-its-worse-than-remote-and-office#office-work\" class=\"hash-link\" aria-label=\"Direct link to Office Work\" title=\"Direct link to Office Work\">​</a></h2>\n<p>Office also works.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"advantages-1\">Advantages<a href=\"https://didierlopes.com/blog/hybrid-work-sucks-its-worse-than-remote-and-office#advantages-1\" class=\"hash-link\" aria-label=\"Direct link to Advantages\" title=\"Direct link to Advantages\">​</a></h3>\n<ol><li><strong>Enhanced company culture:</strong> Offices contribute to a shared sense of identity and mission.</li><li><strong>Face-to-face collaboration:</strong> It allows for immediate interaction, fostering effective teamwork and problem-solving.</li><li><strong>Social interaction:</strong> Offices provide opportunities for building relationships with coworkers, enhancing camaraderie.</li><li><strong>Clear work-life boundaries:</strong> Physical office spaces establish separation between work and personal life.</li><li><strong>Mentorship and learning:</strong> In-person environments facilitate mentorship and hands-on learning.</li><li><strong>Improved supervision:</strong> Physical presence aids in monitoring performance and providing timely feedback.</li></ol>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"disadvantages-1\">Disadvantages<a href=\"https://didierlopes.com/blog/hybrid-work-sucks-its-worse-than-remote-and-office#disadvantages-1\" class=\"hash-link\" aria-label=\"Direct link to Disadvantages\" title=\"Direct link to Disadvantages\">​</a></h3>\n<ol><li><strong>Commuting and transportation issues:</strong> Office work often involves commuting, which can lead to time-consuming and stressful travel, traffic congestion, and transportation expenses.</li><li><strong>Lack of flexibility:</strong> Office work typically follows a fixed schedule, leaving less room for personal flexibility or adjustments to achieve work-life balance.</li><li><strong>Office politics:</strong> Office environments can sometimes involve office politics, conflicts, or gossip that can affect productivity and job satisfaction.</li><li><strong>High overhead costs:</strong> Maintaining physical office spaces can be costly for organizations, including expenses related to rent, utilities, and office supplies.</li><li><strong>Limited geographic talent pool:</strong> Offices are often location-dependent, which may restrict access to a diverse and global talent pool, potentially limiting the variety of skills and perspectives within a workforce.</li><li><strong>Distractions and interruptions:</strong> Open office layouts or noisy work environments can lead to frequent interruptions, reducing focus and productivity.</li></ol>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"conclusion-1\">Conclusion<a href=\"https://didierlopes.com/blog/hybrid-work-sucks-its-worse-than-remote-and-office#conclusion-1\" class=\"hash-link\" aria-label=\"Direct link to Conclusion\" title=\"Direct link to Conclusion\">​</a></h3>\n<p>Office works. Most workers are used to office work, and there’s a reason why it works so well, because it is easy for both the employee and the employer.</p>\n<p><strong>From the employee standpoint:</strong> The routine of waking up, commuting, working for eight hours, commuting back, and then enjoying the evening is straightforward and requires minimal scheduling or organization. The job begins when the employee arrives at the office and ends when they leave. However, it’s important to note that this fixed schedule does not necessarily guarantee peak performance throughout the entire workday.</p>\n<p>For senior engineers, mentorship and learning opportunities may lead to context switching, disrupting deep focused work. What some refer to social interaction, can be perceived as wasting company resources. While supervision can raise the bar for average workers, top performers do not require constant supervision to excel. So if you’re aiming for top performers, perhaps supervision isn’t really necessary at all?</p>\n<p><strong>From the employer standpoint:</strong> Leaders and managers may find it easier to have everyone in the office for quick communication and check-ins. However, relying on in-person communication may result in less documentation, which can be challenging for new joiners. Supervision becomes simpler as managers can track attendance and check on employees throughout the day, but this can also lead to time wasted for both the manager and the person being supervised. (Plus even that supervision allowed “A day in a life of” viral TikToks to highlighted inefficiencies).</p>\n<p><strong>In conclusion, I’d say that your average worker will be better in the office, while your top performers will excel further in a remote environment.</strong></p>\n<blockquote>\n<p><em>The question is whether you prefer your top engineers to become 10x more productive working remotely or prefer your average engineers to improve performance by 2x. Personally, I prefer to aim for 10x productivity with top engineers and let go of average ones.</em></p>\n</blockquote>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"hybrid-work\">Hybrid Work<a href=\"https://didierlopes.com/blog/hybrid-work-sucks-its-worse-than-remote-and-office#hybrid-work\" class=\"hash-link\" aria-label=\"Direct link to Hybrid Work\" title=\"Direct link to Hybrid Work\">​</a></h2>\n<p>Ok, now that we’ve discussed remote and office work, let’s go over why hybrid work sucks.</p>\n<p>People in general tend to associate hybrid work with the best of remote and the best of office, but I think that the worst of remote and office have more emphasis. Let’s go over the biggest pain points:</p>\n<ol><li><strong>Decreased productivity:</strong> When compared with remote or office, hybrid has lower productivity. This is due to the context switching associated with changing working environments. Personally, I have experienced this and found it frustrating to work until late at night, packing up and thinking about what I needed to carry for the next day, plus commuting. The next day, it took me much longer to get back into the flow of work compared to waking up and immediately continuing with the problem at hand.</li><li><strong>Decreased flexibility:</strong> Hybrid work offers less flexibility than remote work but somewhat more than office work. However, this flexibility is often constrained by company policies, such as designated office and remote days or specific rules regarding remote work. When the company dictates the days employees can work remotely, the flexibility becomes somewhat artificial.</li><li><strong>Communication challenges:</strong> As mentioned earlier, one of the reasons that office communication is a sword of 2 edges is because while in-person communication can be effective and fast, it often results in less documentation, which can impact new joiners. In a hybrid culture, this issue is so much worse, because it’s hard to get the company aligned into the amount of level of documentation necessary. Plus, when WFH days rotate across divisions and teams, individuals working remotely may suffer from a lack of context that is shared among the team in the office, leading to silos and communication gaps.In addition to that in remote work employees can and expect to have to accommodate for different time zones but when you move people to hybrid the ones that need to go to the office will no longer adjust their times to match the ones WFH based on needs.</li><li><strong>Blurred work-life boundaries:</strong> Hybrid work blurs the line between work and personal life. It no longer solely involves working from home and spending time with family but also includes being at work, interacting with co-workers, and commuting. This blurring can make it difficult to establish clear boundaries.</li><li><strong>Limited geographic talent pool:</strong> Since you want employees to commute to the office a certain number of times per week or month, you can’t hire them from anywhere. The geographic scope of talent acquisition becomes restricted, potentially limiting access to diverse skills and perspectives.</li><li><strong>Many more distractions:</strong> Individuals face distractions both at home when working remotely and in the office from co-workers. PLUS, you get the distractions that come from your co-workers bringing you up to speed if something happened when you weren’t in the office the day before (similar to the additional amount of chit chat that happens on Mondays due to weekend).</li><li><strong>Costs and commuting:</strong> You may save some money with some WFH, but often the WFH days don’t even justify going into a lower tier than a monthly subscription to public transports. So you end up spending the same, even if you travel less. This argument is less valid here in the Bay area where most people drive. Plus commuting those 3/4 days a week, is still a pain.When we talk about the employer costs then it’s impossible to get it right. On the one hand you have too few people in the office which means you are overpaying for office space, on the other hand you cannot get everyone in. And this will always be impossible with a growing team + managing the WFH days of each team and division.</li><li><strong>Decreased employee retention and satisfaction:</strong> In general, people tend to lean towards either remote work or office work. With hybrid work, those who prefer the office environment may work in the office most days, using WFH as an opportunity for personal tasks and potentially being less productive. On the other hand, those who prefer remote work will aim to WFH as much as possible and may feel dissatisfied with having to go to the office for the remaining days This can create a divide and decrease overall employee satisfaction. Additionally, this is even more pronounced when everyone in the leadership works in the office, since the company tends to follow culture from leaders and will have less incentives to accommodate team members that are not in the office.</li><li><strong>Challenges with supervision:</strong> Physical presence in the office often aids in monitoring performance, but it becomes challenging to fairly evaluate the performance of team members in the office versus those working remotely in a hybrid setup. What is the basis that you use to evaluate them? Based on what you see when they are in the office? Do you still create ways to evaluate their output when WFH? Do you still check on them as often when the rest of your team is with you in the office? What about when you are WFH and have half of the team in the office and the other WFH? The amount of complexity that comes from managing this by itself, almost makes hybrid the worst choice.</li></ol>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"conclusion-2\">Conclusion<a href=\"https://didierlopes.com/blog/hybrid-work-sucks-its-worse-than-remote-and-office#conclusion-2\" class=\"hash-link\" aria-label=\"Direct link to Conclusion\" title=\"Direct link to Conclusion\">​</a></h2>\n<p>I’m not saying that hybrid work can’t work, but my point is that people tend to use hybrid as the perfect solution between office and remote, and I don’t think it is. In fact, I think for most companies, this is a way to sweep a problem under the rug with a half-baked solution.</p>\n<p>As an engineer, I wouldn’t be happy working in an office because I know I could contribute much more to the company by working from home. I’d be “okay” with doing hybrid work in order to continue working for the company, but I would probably start looking elsewhere due to all the aforementioned issues.</p>\n<p>As a leader, OpenBB has started as a remote company, and as a result, we have become highly efficient at working remotely, even when dealing with a 9-hour time difference. All team members understand that they need to make compromises with their working hours to accommodate the company’s needs. <em>So, it ultimately comes down to the type of team you are building and how committed they are to the mission, as well as how you can cultivate such a culture internally.</em></p>\n<p>If your team grew accustomed to working in an office and had to switch to remote due to COVID, and you are noticing a decrease in performance, it may be that your team was not prepared to work remotely. In that case, it makes sense to go back to the office. However, if your team grew while working remotely, and you are not satisfied with their performance, let me tell you that bringing the team back to the office is a half-baked solution. Instead, it would be better to investigate the issue and implement better processes or address underperforming individuals.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/hybrid-work-sucks-its-worse-than-remote-and-office",
            "title": "Hybrid work sucks. It’s worse than remote and office.",
            "summary": "Hybrid work, a combination of remote and office work, is not as beneficial as it seems. This blog post discusses the pros and cons of remote and office work, and why hybrid work might not be the best solution.",
            "date_modified": "2023-06-12T00:00:00.000Z",
            "tags": [
                "remote-work",
                "office-work",
                "hybrid-work",
                "productivity",
                "work-culture"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/become-an-openbb-champion",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2023-06-10-become-an-openbb-champion.webp\"></p>\n<br>\n<p>Become an OpenBB Champion and join our passionate community. Share your experiences with our innovative products and help us democratize investment research through an open source approach.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>Do you find yourself unable to live without one of OpenBB’s innovative products? Have you pushed the boundaries of our tools and unlocked their full potential? If you answered yes, then this blog post is tailor-made for you!</p>\n<p>At <a href=\"https://openbb.co/\" target=\"_blank\" rel=\"noopener noreferrer\">OpenBB</a>, we are actively seeking out <a href=\"https://my.openbb.co/app/hub/champions\" target=\"_blank\" rel=\"noopener noreferrer\">OpenBB Champions</a> — passionate community members who share our vision of democratizing investment research through an open source approach.</p>\n<p>Whether you utilize the <a href=\"https://my.openbb.co/app/terminal\" target=\"_blank\" rel=\"noopener noreferrer\">OpenBB Terminal</a> to streamline your investment research workflow, leverage the <a href=\"https://my.openbb.co/app/sdk\" target=\"_blank\" rel=\"noopener noreferrer\">OpenBB SDK</a> to create your own internal dashboards and notebooks, or employ the <a href=\"https://my.openbb.co/app/bot\" target=\"_blank\" rel=\"noopener noreferrer\">OpenBB Bot</a> to extract financial data within your finance community, we want to hear from you!</p>\n<p>To qualify as an OpenBB Champion, you need to be an active user of one of our products and be willing to share your valuable experiences with our team. We’re eager to learn more about your journey with OpenBB and how our products have transformed your workflow.</p>\n<p align=\"center\"><img width=\"400\" src=\"https://didierlopes.com/blog/2023-06-10-become-an-openbb-champion_1.webp\"></p>\n<br>\n<p><strong>Where's what we would like to know:</strong></p>\n<ul>\n<li>Your background</li>\n<li>How you heard about OpenBB</li>\n<li>Workflow transformation since incorporating OpenBB into your toolkit</li>\n<li>Your favorite OpenBB product</li>\n<li>Your favorite feature within that product</li>\n<li>Future expectations from us</li>\n<li>Your end goal — ultimate objective or milestone</li>\n</ul>\n<p>As an OpenBB Champion, your contribution will not go unnoticed. Here are the benefits you’ll receive:</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"exposure\">Exposure<a href=\"https://didierlopes.com/blog/become-an-openbb-champion#exposure\" class=\"hash-link\" aria-label=\"Direct link to Exposure\" title=\"Direct link to Exposure\">​</a></h3>\n<p>Your testimonial will be prominently featured on OpenBB’s website, social media channels, and other marketing materials. This exposure will introduce your expertise to a wider audience, increasing your visibility within the investment research community.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"recognition\">Recognition<a href=\"https://didierlopes.com/blog/become-an-openbb-champion#recognition\" class=\"hash-link\" aria-label=\"Direct link to Recognition\" title=\"Direct link to Recognition\">​</a></h3>\n<p>You will be officially recognized as an OpenBB Champion, highlighting your commitment to innovation and industry-leading practices. This recognition can bolster your credibility and authority in your field of expertise.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"networking\">Networking<a href=\"https://didierlopes.com/blog/become-an-openbb-champion#networking\" class=\"hash-link\" aria-label=\"Direct link to Networking\" title=\"Direct link to Networking\">​</a></h3>\n<p>As part of the OpenBB Champion community, you will have exclusive access to networking opportunities with like-minded individuals who share your passion for OpenBB’s products. Forge meaningful connections, exchange ideas, and collaborate with fellow champions to amplify your impact.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"merchandise\">Merchandise<a href=\"https://didierlopes.com/blog/become-an-openbb-champion#merchandise\" class=\"hash-link\" aria-label=\"Direct link to Merchandise\" title=\"Direct link to Merchandise\">​</a></h3>\n<p>To show our appreciation for your support, the OpenBB team will send you exclusive OpenBB merchandise. Wear it proudly and let others know that you are part of our journey.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>If you meet the requirements and are enthusiastic about becoming an <a href=\"https://openbb.co/blog?type=champions\" target=\"_blank\" rel=\"noopener noreferrer\">OpenBB Champion</a>, we invite you to reach out to us at <a href=\"mailto:hello@openbb.finance\" target=\"_blank\" rel=\"noopener noreferrer\">hello@openbb.finance</a>. Our team will coordinate a podcast session with you.</p>\n<p>We look forward to hearing from you.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/become-an-openbb-champion",
            "title": "Become an OpenBB Champion",
            "summary": "Become an OpenBB Champion and join our passionate community. Share your experiences with our innovative products and help us democratize investment research through an open source approach.",
            "date_modified": "2023-06-10T00:00:00.000Z",
            "tags": [
                "openbb",
                "openbb-champion",
                "investment-research",
                "open-source",
                "community"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/streamline-your-openbb-terminal-experience-with-openbb-hub",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2023-05-25-streamline-your-openbb-terminal-experience-with-openbb-hub.webp\"></p>\n<br>\n<p>Streamline your OpenBB Terminal experience with OpenBB Hub. Learn about its key features, including API key management, data customization, personalization, and script management.</p>\n<p>The open source code is available <a href=\"https://github.com/openbb-finance/OpenBBTerminal\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>If you’re using the OpenBB Terminal, there’s an essential component you shouldn’t miss out on: the <a href=\"https://my.openbb.co/\" target=\"_blank\" rel=\"noopener noreferrer\">OpenBB Hub</a>. In this blog post, we’ll explore the significance of OpenBB Hub and why it truly matters for OpenBB users.</p>\n<p>By delving into its key features, we’ll uncover how OpenBB Hub elevates your experience with the OpenBB Terminal, providing you with enhanced capabilities and customization options. Let’s dive in!</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"login\">Login<a href=\"https://didierlopes.com/blog/streamline-your-openbb-terminal-experience-with-openbb-hub#login\" class=\"hash-link\" aria-label=\"Direct link to Login\" title=\"Direct link to Login\">​</a></h2>\n<p>As highlighted in our previous blog post <a href=\"https://openbb.co/blog/introducing-the-openbb-hub\" target=\"_blank\" rel=\"noopener noreferrer\">Introducing the OpenBB Hub</a>, the OpenBB Hub is more than just a platform to access the OpenBB product ecosystem; it adds value to each individual product. Specifically, when it comes to the OpenBB Terminal, having an OpenBB Hub account offers tremendous advantages.</p>\n<p>Notably, the settings and features you configure within the hub persist across terminal updates and even when you log in from a new machine, allowing for a seamless and personalized experience.</p>\n<div class=\"flex place-items-center justify-center items-center rounded-sm mx-auto\"><iframe src=\"https://www.youtube.com/embed/HNEZ6h2K9C4?si=qD9OmbHo9SGEkUM5\" width=\"800\" height=\"400\"></iframe></div>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"streamlining-api-key-management\">Streamlining API key management<a href=\"https://didierlopes.com/blog/streamline-your-openbb-terminal-experience-with-openbb-hub#streamlining-api-key-management\" class=\"hash-link\" aria-label=\"Direct link to Streamlining API key management\" title=\"Direct link to Streamlining API key management\">​</a></h2>\n<p>A common question we receive is about the source of our data. OpenBB doesn’t own any data; instead, we enable users to access data from various vendors by signing up for plans on their respective websites. This approach allows us to focus on platform development and data standardization while giving users the freedom to pay for the high-quality datasets they desire.</p>\n<p>Previously, managing API keys was only accessible through the terminal CLI, which could be suboptimal. To alleviate this, we introduced the capability to manage API keys directly from a web page, reducing friction and putting the focus back on what matters most: access to data.</p>\n<div class=\"flex place-items-center justify-center items-center rounded-sm mx-auto\"><iframe src=\"https://www.youtube.com/embed/IrHMEuWQiiQ?si=usaVWmOOWRPqEakq\" width=\"800\" height=\"400\"></iframe></div>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"enhanced-data-customization\">Enhanced data customization<a href=\"https://didierlopes.com/blog/streamline-your-openbb-terminal-experience-with-openbb-hub#enhanced-data-customization\" class=\"hash-link\" aria-label=\"Direct link to Enhanced data customization\" title=\"Direct link to Enhanced data customization\">​</a></h2>\n<p>With OpenBB Hub, you have the power to set default data sources, enabling you to choose the data vendor that aligns best with your needs for each command within the terminal. This flexibility empowers you to curate your preferred data sources, providing a tailored experience that optimizes your decision-making process.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"infuse-personal-style-into-your-terminal\">Infuse personal style into your terminal<a href=\"https://didierlopes.com/blog/streamline-your-openbb-terminal-experience-with-openbb-hub#infuse-personal-style-into-your-terminal\" class=\"hash-link\" aria-label=\"Direct link to Infuse personal style into your terminal\" title=\"Direct link to Infuse personal style into your terminal\">​</a></h2>\n<p>OpenBB Hub lets you personalize your terminal by customizing its colors to your liking. From the command line interface menu to interactive tables and even charting colors, you have the freedom to create your own custom color scheme. Whether you prefer soothing pastel shades or bold neon colors, the choice is yours.</p>\n<p>This feature not only adds a touch of personalization but also ensures a comfortable and visually pleasing experience, reducing eye strain during extended usage. Say goodbye to the standard white background and say hello to a terminal that reflects your unique style.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"effortless-routine-scripts-management\">Effortless routine scripts management<a href=\"https://didierlopes.com/blog/streamline-your-openbb-terminal-experience-with-openbb-hub#effortless-routine-scripts-management\" class=\"hash-link\" aria-label=\"Direct link to Effortless routine scripts management\" title=\"Direct link to Effortless routine scripts management\">​</a></h2>\n<p>We’ve noticed a growing trend among our users: the development and adoption of routine scripts. These .openbb files contain OpenBB commands and allow users to save their investment research workflows, as well as share them with others.</p>\n<p>While OpenBB Hub provides access to pre-defined scripts developed by our team, which have been extensively used in academia, it also allows you to manage your own scripts. In the near future, we will introduce a community scripts page, fostering script sharing and discussions on individual use cases.</p>\n<div class=\"flex place-items-center justify-center items-center rounded-sm mx-auto\"><iframe src=\"https://www.youtube.com/embed/S0PIl8qEBCo?si=Lc4u2bG_NRWNhRhf\" width=\"800\" height=\"400\"></iframe></div>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"final-thoughts\">Final thoughts<a href=\"https://didierlopes.com/blog/streamline-your-openbb-terminal-experience-with-openbb-hub#final-thoughts\" class=\"hash-link\" aria-label=\"Direct link to Final thoughts\" title=\"Direct link to Final thoughts\">​</a></h2>\n<p>The OpenBB Hub has become the central platform where we closely engage with the community, continuously striving to add value to your experience when utilizing our suite of products. We encourage you to share your feedback and ideas with us to help shape the future of OpenBB.</p>\n<p>Join the OpenBB Hub today, and spread the word among your peers, so we can grow together and create an even more vibrant community.</p>\n<p>Check out the OpenBB Hub user metrics <a href=\"https://openbb.co/company/open?type=hub\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>, and if you missed our recent webinar, you can catch up on all the exciting new features in the video below.</p>\n<div class=\"flex place-items-center justify-center items-center rounded-sm mx-auto\"><iframe src=\"https://www.youtube.com/embed/_4dQs_q_Jtk?si=Wqu2vi2EWUww3gfK\" width=\"800\" height=\"400\"></iframe></div>\n<br>\n<p>With the <a href=\"https://my.openbb.co/\" target=\"_blank\" rel=\"noopener noreferrer\">OpenBB Hub</a>, you unlock a world of possibilities.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/streamline-your-openbb-terminal-experience-with-openbb-hub",
            "title": "Streamline your OpenBB Terminal experience with OpenBB Hub",
            "summary": "Streamline your OpenBB Terminal experience with OpenBB Hub. Learn about its key features, including API key management, data customization, personalization, and script management.",
            "date_modified": "2023-05-25T00:00:00.000Z",
            "tags": [
                "openbb",
                "openbb-hub",
                "terminal",
                "api-key-management",
                "data-customization",
                "personalization",
                "script-management"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/openbb-terminal-3-0-a-new-interactive-way-to-analyze-data",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2023-05-20-openbb-terminal-3-0-a-new-interactive-way-to-analyze-data.webp\"></p>\n<br>\n<p>A game-changing update to OpenBB Terminal, introducing interactive charts and tables, empowering users with a new way to analyze data.</p>\n<p>The open source code is available <a href=\"https://github.com/openbb-finance/OpenBBTerminal\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>Nothing has changed, yet everything is different. A game-changing update empowering users with interactive charts and tables</p>\n<p>Our commitment to listening to user feedback and continuously improving our platform has led to a major update that will revolutionize the way you analyze data.</p>\n<p>One of the main requests from our community has been regarding the interactivity of the charts and tables output by the <a href=\"https://my.openbb.co/app/terminal\" target=\"_blank\" rel=\"noopener noreferrer\">OpenBB Terminal</a>. We are happy to say that we have delivered on this request with a complete overhaul of the terminal plotting library.</p>\n<p>Not only that, but our engineering team wasn’t happy with the technical solutions available to bring interactivity to the terminal. So, in a true open-source fashion, the team built our own open-source library which will be announced soon.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"interactive-charts\">Interactive charts<a href=\"https://didierlopes.com/blog/openbb-terminal-3-0-a-new-interactive-way-to-analyze-data#interactive-charts\" class=\"hash-link\" aria-label=\"Direct link to Interactive charts\" title=\"Direct link to Interactive charts\">​</a></h2>\n<div class=\"flex place-items-center justify-center items-center rounded-sm mx-auto\"><iframe src=\"https://www.youtube.com/embed/oAUK-kC0uv0?si=A_5ZxITto7ADgJ2V\" width=\"800\" height=\"400\"></iframe></div>\n<br>\n<p>One of the most significant additions in this update is the introduction of interactive charts. Gone are the days of static data representations.</p>\n<p>With the OpenBB Terminal, you can now immerse yourself in a dynamic visual experience. Hover over specific data points to reveal detailed information, or effortlessly adjust the charts using intuitive pan and zoom capabilities. But that’s not all — our drawing tools and annotations allow you to highlight crucial data points and ranges, giving you complete control over your analysis.</p>\n<p>Through our user interviews, we discovered that many users faced challenges when overlaying financial time series. Taking this into account, we’ve designed our new charting feature to make this process seamless. With the ability to easily overlay time series data and combine it with our powerful data exporting capabilities, OpenBB Terminal empowers you to perform in-depth analysis with unparalleled ease and precision.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"interactive-tables\">Interactive tables<a href=\"https://didierlopes.com/blog/openbb-terminal-3-0-a-new-interactive-way-to-analyze-data#interactive-tables\" class=\"hash-link\" aria-label=\"Direct link to Interactive tables\" title=\"Direct link to Interactive tables\">​</a></h2>\n<div class=\"flex place-items-center justify-center items-center rounded-sm mx-auto\"><iframe src=\"https://www.youtube.com/embed/GNh7RQBHNUc?si=GKf7hYaR7VQKBLp-\" width=\"800\" height=\"400\"></iframe></div>\n<br>\n<p>We listened to our users’ concerns about readability when dealing with large tables, and we have addressed these challenges head-on. The OpenBB Terminal now boasts interactive tables that are as aesthetically pleasing as they are functional.</p>\n<p>Leveraging our innovative open-source project, we have crafted a state-of-the-art table that is easy on the eyes and effortlessly responsive. Sorting, filtering, and manipulating table data has never been easier. This game-changing feature enables you to quickly and efficiently extract insights from vast amounts of data, enhancing your productivity and saving valuable time.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"new-fixed-income-menu\">New fixed income menu<a href=\"https://didierlopes.com/blog/openbb-terminal-3-0-a-new-interactive-way-to-analyze-data#new-fixed-income-menu\" class=\"hash-link\" aria-label=\"Direct link to New fixed income menu\" title=\"Direct link to New fixed income menu\">​</a></h2>\n<div class=\"flex place-items-center justify-center items-center rounded-sm mx-auto\"><iframe src=\"https://www.youtube.com/embed/mLa4rcDfYTE?si=cQkz9BYJTCZ0cTwx\" width=\"800\" height=\"400\"></iframe></div>\n<br>\n<p>In addition to the remarkable advancements in interactivity, we have squashed bugs and introduced a new Fixed Income menu. This means you now have access to an even wider range of data to fuel your analysis. OpenBB Terminal ensures that you are equipped with the right tools to gain a competitive edge in your investment research.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"wrap-up---embrace-the-future-of-data-analysis\">Wrap up - embrace the future of data analysis<a href=\"https://didierlopes.com/blog/openbb-terminal-3-0-a-new-interactive-way-to-analyze-data#wrap-up---embrace-the-future-of-data-analysis\" class=\"hash-link\" aria-label=\"Direct link to Wrap up - embrace the future of data analysis\" title=\"Direct link to Wrap up - embrace the future of data analysis\">​</a></h2>\n<p>We firmly believe that these new features will take your user experience to new heights and unlock a realm of possibilities for data analysis. Our dedicated team has poured countless hours into bringing these cutting-edge features to life, and we cannot wait to witness the impact they will have on your work.</p>\n<p>To further amplify our commitment to open source, we will open source a powerful project that taps into web browser functionality from Python, opening up endless opportunities for developers and data enthusiasts.</p>\n<p>We value your feedback and are eager to iterate on the OpenBB Terminal to ensure it meets your evolving needs. Reach out to us via email at <a href=\"mailto:hello@openbb.finance\" target=\"_blank\" rel=\"noopener noreferrer\">hello@openbb.finance</a>, Twitter, or Discord and let us know how we can enhance your experience further.</p>\n<p>If you missed our exciting webinar unveiling these transformative features, fear not! We’ve got you covered. Watch the video below to catch up and witness firsthand the incredible new capabilities our team has unleashed.</p>\n<div class=\"flex place-items-center justify-center items-center rounded-sm mx-auto\"><iframe src=\"https://www.youtube.com/embed/_4dQs_q_Jtk?si=1BRr1pF2SRrkC3lZ\" width=\"800\" height=\"400\"></iframe></div>\n<br>\n<p>Welcome to a new era of data analysis with OpenBB Terminal. Get ready to explore, discover, and gain a competitive edge like never before.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/openbb-terminal-3-0-a-new-interactive-way-to-analyze-data",
            "title": "OpenBB Terminal 3.0 - a new interactive way to analyze data",
            "summary": "A game-changing update to OpenBB Terminal, introducing interactive charts and tables, empowering users with a new way to analyze data.",
            "date_modified": "2023-05-20T00:00:00.000Z",
            "tags": [
                "openbb",
                "openbb-terminal",
                "interactive-charts",
                "interactive-tables",
                "data-analysis",
                "open-source"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/leaving-london-to-live-in-san-francisco",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2023-05-13-leaving-london-to-live-in-san-francisco.webp\"></p>\n<br>\n<p>Leaving London to live in San Francisco: A personal journey of relocating and starting a tech company in the heart of Silicon Valley.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"background\">Background<a href=\"https://didierlopes.com/blog/leaving-london-to-live-in-san-francisco#background\" class=\"hash-link\" aria-label=\"Direct link to Background\" title=\"Direct link to Background\">​</a></h2>\n<p>I was born in Geneva, and when I was 8 years old, we moved back to Portugal, which is where my parents are originally from. After spending most of my teenage years in Portugal, I left sunny Lisbon ☀️ to pursue a MSc. degree at Imperial College London 💻. That’s where I’ve been living and working up until now. The main reasons behind my desire to move to San Francisco ☀️ 💻 are the weather and the thriving tech ecosystem that surrounds it.</p>\n<p>During the Covid pandemic while in London, I took the opportunity to build my own <a href=\"https://github.com/OpenBB-finance/OpenBBTerminal\" target=\"_blank\" rel=\"noopener noreferrer\">personal open source investment research platform</a>. This project allowed me to secure VC funding and establish a company called <a href=\"https://openbb.co/\" target=\"_blank\" rel=\"noopener noreferrer\">OpenBB</a>. As the CEO of this company, I feel privileged to have the chance to make a lasting impact on the financial industry. Embracing this adventure and collaborating with individuals who are much smarter than I am is the least I can do for our team and for OpenBB.</p>\n<p>As a first-time founder, I often find myself feeling slightly behind, which is why I’m eager to absorb as much experience and knowledge as possible from other successful entrepreneurs. This is also why I managed to convince my wife and our dogs to join me in packing our bags and embarking on this journey into the unknown, much like my Portuguese ancestors did centuries ago 🚢.</p>\n<p>Now, let’s dive into what truly matters. This will be a lengthy ride, so make sure you’re prepared for the journey ahead.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"visa\">VISA<a href=\"https://didierlopes.com/blog/leaving-london-to-live-in-san-francisco#visa\" class=\"hash-link\" aria-label=\"Direct link to VISA\" title=\"Direct link to VISA\">​</a></h2>\n<p>First of all, you need to determine which visa you are eligible for in order to live and work in the US. You can find more information on this topic <a href=\"https://travel.state.gov/content/travel/en/us-visas.html\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<p>In my case, I decided to apply for an “O-1 Visa: Individuals with Extraordinary Ability or Achievement” and specifically highlighted my extraordinary ability in the field of Computer Science, specifically within the subfield of Automated Systems. It is crucial to specify a particular field to make the defense process smoother.</p>\n<p>I had the privilege of working with an exceptional immigration lawyer who assisted me in crafting my case, significantly increasing my chances of a successful approval. Here is a portion of the O-1 Petition that was submitted:</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2023-05-13-leaving-london-to-live-in-san-francisco_1-4ae0008bcba7d54b0afe1ee2a4499c19.webp\" width=\"1400\" height=\"512\" class=\"img_ev3q\"></p>\n<p>As you can see, there is quite a bit of paperwork required to support your case. In my situation, I needed the following documents: Curriculum Vitae, university grades, transcripts and diplomas, LinkedIn and GitHub profiles, posts that gained viral attention on platforms like Reddit and HackerNews, podcasts and conferences where I had spoken, projects that received online praise, any media coverage I had received, scholarly scientific publications, expert opinion letters, and even emails or direct messages from venture capitalists or professionals in the industry.</p>\n<p>Essentially, any relevant evidence is used to strengthen your case. For me, the most crucial elements were the expert opinion letters provided by our lead investor, former colleagues, or respected individuals in the field who were familiar with my work, as well as the research papers I had published and the media coverage I had received.</p>\n<p>Once my O-1 visa was approved, I simply needed to take my passport to the US embassy in London to obtain the visa stamp. It’s worth noting that if the wait time at the US embassy is lengthy, you have the option to visit another US embassy in another country where the process may be faster.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"arriving-to-the-country\">Arriving to the country<a href=\"https://didierlopes.com/blog/leaving-london-to-live-in-san-francisco#arriving-to-the-country\" class=\"hash-link\" aria-label=\"Direct link to Arriving to the country\" title=\"Direct link to Arriving to the country\">​</a></h2>\n<p>I arrived in California on my own initially, with the plan for my wife and dogs to join me later. Thankfully, I had some contacts in California who provided me with their phone number and house address, which was helpful for getting settled. Since I didn’t have a phone before finding an apartment, I had to rely on roaming data using my plan from the UK, which resulted in additional expenses.</p>\n<p>I would suggest either having a good deal for data roaming and international calls outside your country or obtaining a prepaid US phone. The latter is especially important if you’re traveling alone because I often encountered registration forms that didn’t accept foreign phone numbers.</p>\n<p>Regarding payments, I used my Revolut VISA card, which offers excellent foreign exchange rates for converting pounds to dollars. It’s worth noting that I couldn’t open a US bank account without a Social Security Number (SSN).</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"social-security-number-ssn\">Social Security Number (SSN)<a href=\"https://didierlopes.com/blog/leaving-london-to-live-in-san-francisco#social-security-number-ssn\" class=\"hash-link\" aria-label=\"Direct link to Social Security Number (SSN)\" title=\"Direct link to Social Security Number (SSN)\">​</a></h3>\n<p>If you know someone in the US, it is advisable to apply for a Social Security Number (SSN) as soon as possible and provide their address and contact information if you don’t have a US address of your own. An SSN is necessary for various purposes, and it may take up to two weeks for the card to arrive. When going to you nearest Social Security Administration (SSA) office, I would suggest arriving 30 minutes before opening hours to avoid long queues.</p>\n<p>To apply for an SSN, you will need to bring the following documents to the SSA office: your passport, the I-797 form (O-1 visa approval notice), and the I-94 form (arrival record in the US).</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"transportation\">Transportation<a href=\"https://didierlopes.com/blog/leaving-london-to-live-in-san-francisco#transportation\" class=\"hash-link\" aria-label=\"Direct link to Transportation\" title=\"Direct link to Transportation\">​</a></h3>\n<p>I had the fortunate opportunity of having a friend lend me a car as soon as I arrived in California, and it made my life ten times easier. I highly recommend having something lined up in terms of transportation, as having a car enables you to get anywhere you need to go much more efficiently. To ensure I was covered, I simply needed to arrange car insurance. I opted for <a href=\"https://www.progressive.com/\" target=\"_blank\" rel=\"noopener noreferrer\">Progressive</a>, and the process was quick and straightforward.</p>\n<p>While settling in, I occasionally relied on public transportation instead of driving, especially when traveling to the center of San Francisco. It took me some time to adjust to driving in the US, so public transport was a convenient alternative. If you plan on using public transportation services like BART or Caltrain, I suggest visiting <a href=\"https://www.iliveinthebayarea.com/knowledge-center/transit/\" target=\"_blank\" rel=\"noopener noreferrer\">this website</a> that provides information on available transportation options. It’s also a good idea to purchase a <a href=\"https://www.clippercard.com/\" target=\"_blank\" rel=\"noopener noreferrer\">Clipper card</a>, which allows you to load funds and easily tap it when boarding.</p>\n<p>Additionally, if you anticipate passing through tolls, bridges, or utilizing the fast lane on the freeway, I recommend looking into acquiring a <a href=\"https://www.thetollroads.com/accounts/fastrak/transponder/\" target=\"_blank\" rel=\"noopener noreferrer\">Fastrack transponder</a> for a more seamless experience.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"finding-an-apartment\">Finding an apartment<a href=\"https://didierlopes.com/blog/leaving-london-to-live-in-san-francisco#finding-an-apartment\" class=\"hash-link\" aria-label=\"Direct link to Finding an apartment\" title=\"Direct link to Finding an apartment\">​</a></h2>\n<p>Apartment hunting proved to be quite stressful, considering that every day spent searching meant unnecessary expenses piling up while I still had my company to manage.</p>\n<p>Using Uber for transportation was convenient and efficient, but the costs could add up quickly with multiple trips. To save money, I recommend scheduling house viewings on the same day in specific areas of interest and simply walking from one location to another.</p>\n<p>While dealing with lease agents, I encountered a mix of competence levels. Some were highly efficient, while others were less so. If you’re genuinely interested in a particular apartment, it’s important to exert some pressure to keep the process moving forward. Don’t hesitate to call and inquire about updates.</p>\n<p>I was fond of the first house we saw, so I promptly paid $300, which covered certain fees. These fees were refundable if we decided not to proceed, but more importantly, they ensured that the house would be taken off the market. At this stage, both the agents and I wanted the process to move as quickly as possible. In our case, the target timeframe was three business days; if the process exceeded that, the house would be made available again.</p>\n<p>Even if you believe you’ve found the perfect apartment, I still recommend continuing your search until the lease contract is signed. It’s crucial to secure the apartment before assuming it’s yours.</p>\n<p>Before obtaining the keys, we had several tasks to complete: making the first payment, setting up utilities (<a href=\"https://www.pge.com/\" target=\"_blank\" rel=\"noopener noreferrer\">PG&amp;E</a> for Gas and Electricity, and <a href=\"https://utilitiesinfo.conservice.com/\" target=\"_blank\" rel=\"noopener noreferrer\">Conservice</a> for water), providing proof of renter’s liability insurance (I used <a href=\"https://assurantrenters.com/\" target=\"_blank\" rel=\"noopener noreferrer\">Assurant</a>’s as it was conveniently associated with the community), and undergoing a pet screening (note that certain dog breeds are considered more dangerous and may not be accepted).</p>\n<p>Most importantly, my salary alone wasn’t sufficient to guarantee that we could afford the rent. I needed a guarantor to vouch for me, as Europe does not have the concept of credit ratings.</p>\n<p>Fortunately, our lead investor graciously agreed to be our guarantor when I asked him. Without someone fulfilling this role, I would have had to rely on a third-party service and pay several thousands of dollars, which would have been non-refundable and solely for the right to lease the house. This arrangement seemed rather illogical.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"after-the-apartment\">After the apartment<a href=\"https://didierlopes.com/blog/leaving-london-to-live-in-san-francisco#after-the-apartment\" class=\"hash-link\" aria-label=\"Direct link to After the apartment\" title=\"Direct link to After the apartment\">​</a></h2>\n<p>I needed to notify <a href=\"https://www.uscis.gov/\" target=\"_blank\" rel=\"noopener noreferrer\">USCIS</a> of my new address since the last one on file was associated with the hotel where I was staying. I informed them that my new residence would be the updated address.</p>\n<p>Following that, my dogs flew from the UK using <a href=\"https://www.petsabroaduk.co.uk/\" target=\"_blank\" rel=\"noopener noreferrer\">Pets abroad UK</a>. To save money, my wife didn’t accompany them on the flight; instead, she arranged for them to be transported in the cargo hold of the airplane while I waited at the destination.</p>\n<p>However, I must admit that I didn’t enjoy the experience, and in hindsight, I would have been willing to pay more for my dogs to have a better and safer flight. Although flying them from London, meant that unfortunately cargo was the option due to UK requirements. When I picked them up, they were visibly scared, and both my wife and I held our breath with worry throughout their entire journey. Our dogs’ well-being was of utmost importance to us.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2023-05-13-leaving-london-to-live-in-san-francisco_2-3d47646e964d07507500e421ec12c4e0.webp\" width=\"1400\" height=\"922\" class=\"img_ev3q\"></p>\n<p>The house was mostly empty, so to save money, we acquired a lot of second-hand items for free. It was beneficial to know people in the area who were aware of others with unused items stored in their garages, which we were able to take. To retrieve this furniture and other objects, we either needed to rent a U-Haul (which wasn’t possible without a California driver’s license) or hire a moving company.</p>\n<p>Our next task was to search for second-hand items at significant discounts on websites such as <a href=\"https://sfbay.craigslist.org/\" target=\"_blank\" rel=\"noopener noreferrer\">Craigslist</a>, <a href=\"https://nextdoor.com/\" target=\"_blank\" rel=\"noopener noreferrer\">Nextdoor</a> and <a href=\"https://www.facebook.com/marketplace\" target=\"_blank\" rel=\"noopener noreferrer\">Facebook Marketplace</a>. However, we had to be cautious of scammers and remember that if a deal seemed too good to be true, it probably was.</p>\n<p>Once we had gathered most of the second-hand items, we visited <a href=\"https://www.homedepot.com/\" target=\"_blank\" rel=\"noopener noreferrer\">Home Depot</a> to paint and improve the newly acquired furniture. For the items we couldn’t find second-hand, we made purchases at <a href=\"https://www.costco.com/\" target=\"_blank\" rel=\"noopener noreferrer\">Costco</a>.</p>\n<p>We highly recommend getting an executive membership at Costco as it provides great value for money. Additionally, the gas prices at Costco are significantly cheaper compared to other places we’ve seen.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"wi-fi--mobile-plan\">Wi-Fi + Mobile plan<a href=\"https://didierlopes.com/blog/leaving-london-to-live-in-san-francisco#wi-fi--mobile-plan\" class=\"hash-link\" aria-label=\"Direct link to Wi-Fi + Mobile plan\" title=\"Direct link to Wi-Fi + Mobile plan\">​</a></h3>\n<p>After securing an apartment, I used my passport to visit an <a href=\"https://www.att.com/\" target=\"_blank\" rel=\"noopener noreferrer\">AT&amp;T</a> store. Since I didn’t have my SSN yet, they were accommodating and allowed me to use my passport for identification. However, if you choose a different service provider like Xfinity, you will need your SSN. Before selecting a plan, it’s important to check the coverage in your area to ensure that 4G/5G works well.</p>\n<p>Initially, I set up Wi-Fi through Xfinity, but then I used that as leverage to negotiate a discount with AT&amp;T. This worked because I was interested in a double play package, which included two phone plans and Wi-Fi. As a result, I obtained an e-sim with unlimited 5G data for both myself and my wife, along with Wi-Fi for our home, at a cost of approximately $150 per month.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"shopping\">Shopping<a href=\"https://didierlopes.com/blog/leaving-london-to-live-in-san-francisco#shopping\" class=\"hash-link\" aria-label=\"Direct link to Shopping\" title=\"Direct link to Shopping\">​</a></h3>\n<p>There’s going to be a big shock in terms of prices; at least, we experienced one. Life in the Bay Area is over 2x more expensive than London.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2023-05-13-leaving-london-to-live-in-san-francisco_3-e8eb0474a64743bd986a2704947d1816.webp\" width=\"1248\" height=\"874\" class=\"img_ev3q\"></p>\n<p>So, we started learning how to buy things at a lower cost. Whole Foods is not a viable option as it’s one of the most expensive stores. The 10 items above cost $69.34 on Whole Foods.</p>\n<p>Instead, we now tend to shop at Safeway and always try to time our visits to take advantage of discounts. Many shopping places offer coupons that can help you save a lot of money. Additionally, when you come across products on sale, it’s better to buy them in larger quantities as it’s usually worth it.</p>\n<p>My wife is also a big fan of Trader Joe’s with the prices there being quite reasonable too. They also have a great selection of cheeses which is a must being from Europe.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"after-obtaining-an-ssn\">After obtaining an SSN<a href=\"https://didierlopes.com/blog/leaving-london-to-live-in-san-francisco#after-obtaining-an-ssn\" class=\"hash-link\" aria-label=\"Direct link to After obtaining an SSN\" title=\"Direct link to After obtaining an SSN\">​</a></h2>\n<p>After you obtain your SSN, there are a lot of new things that you are able to do since you are recognized as a “person.”</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"bank-account\">Bank account<a href=\"https://didierlopes.com/blog/leaving-london-to-live-in-san-francisco#bank-account\" class=\"hash-link\" aria-label=\"Direct link to Bank account\" title=\"Direct link to Bank account\">​</a></h3>\n<p>Credit cards are recommended over debit cards, not just because of the security benefits, but also because of the credit rating associated with them. This is a concept that doesn’t really exist in Europe but is significant in the US. Your credit score will determine whether you are approved for a loan and what interest rate you will be charged.</p>\n<p>The agencies that handle your credit score are <a href=\"http://equifax.com/\" target=\"_blank\" rel=\"noopener noreferrer\">Equifax.com</a>, <a href=\"http://transunion.com/\" target=\"_blank\" rel=\"noopener noreferrer\">TransUnion.com</a> and <a href=\"http://experian.com/\" target=\"_blank\" rel=\"noopener noreferrer\">Experian.com</a>. It’s free to register, and you should keep an eye on your credit files to ensure that your credit score doesn’t decrease for any reason.</p>\n<p>We ended up opening an account with <a href=\"https://www.bankofamerica.com/\" target=\"_blank\" rel=\"noopener noreferrer\">Bank of America</a>. However, since we didn’t have a credit score yet, we couldn’t get a regular credit card. Instead, we had to apply for a secured credit card, where the maximum spending limit is determined by the amount of cash we use to back the credit card.</p>\n<p>We also applied for an <a href=\"https://www.americanexpress.com/us/credit-cards/card/blue-cash-everyday/?eep=26129&amp;irgwc=1&amp;veid=39E0XuRS3xyNT4BTy33WSUXYUkAwp0Tx32Qt0c0&amp;affid=1193684&amp;pid=IR&amp;affname=NerdWallet%2C+Inc.&amp;sid=14011830016&amp;pmc=795&amp;BUID=CCG&amp;CRTV=controlaffcps&amp;MPR=03\" target=\"_blank\" rel=\"noopener noreferrer\">AMEX card</a> because <a href=\"https://www.americanexpress.com/\" target=\"_blank\" rel=\"noopener noreferrer\">American Express</a> has a partnership with the international credit-reporting startup Nova Credit. This allows immigrants to instantly translate credit reports from the UK to U.S.-equivalent credit reports when applying for AmEx consumer cards. However, it’s important to note that AMEX cards are less widely accepted compared to VISA and MasterCard, so we were aware that they would only work in certain establishments.</p>\n<p>For more information, these video were extremely helpful:</p>\n<ul>\n<li><a href=\"https://bettermoneyhabits.bankofamerica.com/en/credit/building-credit\" target=\"_blank\" rel=\"noopener noreferrer\">Building credit and keeping yours healthy</a></li>\n<li><a href=\"https://bettermoneyhabits.bankofamerica.com/en/credit/start-building-credit\" target=\"_blank\" rel=\"noopener noreferrer\">How to build credit from scratch</a></li>\n<li><a href=\"https://bettermoneyhabits.bankofamerica.com/en/credit/top-credit-questions\" target=\"_blank\" rel=\"noopener noreferrer\">Top 3 credit questions</a></li>\n</ul>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"car\">Car<a href=\"https://didierlopes.com/blog/leaving-london-to-live-in-san-francisco#car\" class=\"hash-link\" aria-label=\"Direct link to Car\" title=\"Direct link to Car\">​</a></h3>\n<p>It was now time for us to buy a car. We searched online for a few options. There are two things worth considering when buying a used car, as we did:</p>\n<ul>\n<li>Firstly, you can use <a href=\"https://www.kbb.com/car-values/\" target=\"_blank\" rel=\"noopener noreferrer\">https://www.kbb.com/car-values/</a> to research the value of the car. This ensures that you don’t get ripped off and provides an estimate of how much the car is worth based on the details you provide.</li>\n<li>Secondly, you can use <a href=\"https://www.carfax.com/\" target=\"_blank\" rel=\"noopener noreferrer\">https://www.carfax.com/</a> to research a car and its license plate. This helps you understand its accident history and any repairs it has undergone. It provides information about whether there have been major accidents in the car’s history, frequent visits to the mechanic, and whether the repairs were done by authorized mechanics (e.g., BMW) or not.</li>\n</ul>\n<p>If you prefer to play it safe, you can even bring a mechanic with you to the dealership to assess the car’s condition.</p>\n<p>We spoke with individuals, but ultimately decided to buy a car from a dealership because it offered fewer risks compared to buying from individuals. Moreover, the dealership took care of updating the vehicle records, ensuring that the vehicle would be registered under our name. This allowed us to update our car insurance with the Vehicle Identification Number (VIN) of the new vehicle.</p>\n<p>After a few months, we received the California Certificate of Title, which confirmed that I was the legal owner of the vehicle and included important vehicle identification information. Since this was my first car, I had to add an OpenBB reference to the front plate :)</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2023-05-13-leaving-london-to-live-in-san-francisco_4-d86a68124d5373bdb8ab0d9465ea3386.webp\" width=\"1126\" height=\"864\" class=\"img_ev3q\"></p>\n<p>Shoutouts to:</p>\n<ul>\n<li><a href=\"https://www.jiffylube.com/\" target=\"_blank\" rel=\"noopener noreferrer\">Jiffy Lube</a> for their car inspection services, tire inflation, oil changes, and more. They don’t charge for the inspection and only charge for the services performed on the car. We had a great experience with them.</li>\n<li><a href=\"https://www.costco.com/gasoline.html\" target=\"_blank\" rel=\"noopener noreferrer\">Costco gas station</a> for the cheapest gas we’ve found so far.</li>\n</ul>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"health-insurance\">Health Insurance<a href=\"https://didierlopes.com/blog/leaving-london-to-live-in-san-francisco#health-insurance\" class=\"hash-link\" aria-label=\"Direct link to Health Insurance\" title=\"Direct link to Health Insurance\">​</a></h3>\n<p>California offers a portal called <a href=\"https://www.coveredca.com/\" target=\"_blank\" rel=\"noopener noreferrer\">Covered California</a>, which provides state-approved health plans from various insurance companies. If your income is low, the state can subsidize your monthly premium. These plans fall into three categories, each with differences in costs and provider networks:</p>\n<ol><li>HMOs (Health Maintenance Organizations): Typically cheaper than PPOs, HMOs have smaller networks. You need to see your primary care physician before getting a referral to a specialist.</li><li>PPOs (Preferred Provider Organizations): Usually more expensive, PPOs offer a larger network and the ability to see providers outside of the network. You can also see specialists without a referral.</li><li>EPOS (Exclusive Provider Organizations): EPOS plans combine features of HMOs and PPOs. They have exclusive networks like HMOs, making them generally less expensive. However, you can make your own appointments with specialists, similar to PPOs.</li></ol>\n<p>In our case, we chose an HMO called Kaiser. <a href=\"https://healthy.kaiserpermanente.org/northern-california/front-door\" target=\"_blank\" rel=\"noopener noreferrer\">Kaiser</a> is a not-for-profit, all-inclusive healthcare company with its own doctors and hospitals. When selecting the plan within Kaiser, we had to choose between Bronze, Silver, and Gold tiers. These tiers are influenced by three main factors:</p>\n<ol><li><strong>Monthly premium:</strong> The amount you pay each month for health plan coverage. It may be subsidized based on your income and household size.</li><li><strong>Annual deductible:</strong> The amount you must pay before your plan starts covering services.</li><li><strong>Annual maximum out-of-pocket:</strong> The total amount you pay in a calendar year (in addition to monthly premiums) for most services covered by your health care plan.</li></ol>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"california-driving-license\">California Driving License<a href=\"https://didierlopes.com/blog/leaving-london-to-live-in-san-francisco#california-driving-license\" class=\"hash-link\" aria-label=\"Direct link to California Driving License\" title=\"Direct link to California Driving License\">​</a></h3>\n<p>The Department of Motor Vehicles (DMV) is responsible for vehicle registrations and driving licenses in California. When you arrive in California, you can use a foreign driving license for only 10 days, after which you must obtain a California Driving License (CDL).</p>\n<p>To apply for the CDL, you can start the process online by completing the driver’s license application on the <a href=\"https://www.dmv.ca.gov/portal/\" target=\"_blank\" rel=\"noopener noreferrer\">DMV website</a>. This online application saves time by allowing you to fill it out before visiting a DMV field office.</p>\n<p>When you visit the DMV, the employees will review your completed application and request certain documents, including:</p>\n<ul>\n<li>Social Security Number (SSN)</li>\n<li>Unexpired foreign passport with a valid U.S. visa</li>\n<li>Approved I-94 form</li>\n<li>Bank and financial institution records</li>\n<li>Insurance documents</li>\n</ul>\n<p>After submitting the required documents, you will have your picture taken and then proceed to take the written driving test. It’s advisable to practice for the test in advance. As I have many years of driving experience, I personally used practice tests available at <a href=\"https://www.dmv-written-test.com/california/practice-test-1.html\" target=\"_blank\" rel=\"noopener noreferrer\">https://www.dmv-written-test.com/california/practice-test-1.html</a>.</p>\n<p>A few days later, I returned to the DMV to take the written test. The test consists of 36 multiple-choice questions, and you are allowed to fail up to 6 questions. You will immediately know whether you passed or not.</p>\n<p>Upon passing the written test, you will receive a document that allows you to schedule your driving exam. It is recommended to book the exam as soon as possible, as available slots may be several weeks away due to high demand.</p>\n<p>On the day of the driving exam, you will need to bring someone who holds a CDL, the document provided after passing the written exam, and your passport.</p>\n<p>The driving exam evaluates your performance, and you will receive a score sheet outlining the criteria and aspects that will be assessed during the exam. This will give you an idea of what to expect and what the examiners will be evaluating.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2023-05-13-leaving-london-to-live-in-san-francisco_5-662f721134b13fd3c04264d4f52e41c0.webp\" width=\"1400\" height=\"1050\" class=\"img_ev3q\"></p>\n<p>After successfully passing the driving exam, the DMV will issue you a temporary document that serves as your California Driving License (CDL). This temporary document will allow you to legally drive while you wait for your physical CDL to be sent to you by mail.</p>\n<p>It typically takes a few months for the physical CDL to be processed and mailed to your designated address. During this time, you can use the temporary document as proof of your driving privileges in California. Once you receive the physical CDL, you should carry it with you whenever you are driving.</p>\n<p>It’s important to note that the temporary document and the physical CDL have the same validity and serve as official proof of your driver’s license status.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"final-thoughts\">Final thoughts<a href=\"https://didierlopes.com/blog/leaving-london-to-live-in-san-francisco#final-thoughts\" class=\"hash-link\" aria-label=\"Direct link to Final thoughts\" title=\"Direct link to Final thoughts\">​</a></h2>\n<p>I’ve moved countries a few times within Europe, and those moves were much easier than moving to the USA.</p>\n<p>Nonetheless, I think you can get settled within 3 months of moving to the country. So far, we are really enjoying our experience and can’t wait to explore more of the area.</p>\n<p>If you are looking to do the same and want some feedback, feel free to reach out. It helped us a lot to have people who could help us with the move, so I’d love to be able to do the same for others.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/leaving-london-to-live-in-san-francisco",
            "title": "Leaving London to live in San Francisco",
            "summary": "Leaving London to live in San Francisco. A personal journey of relocating and starting a tech company in the heart of Silicon Valley.",
            "date_modified": "2023-05-13T00:00:00.000Z",
            "tags": [
                "san-francisco",
                "london",
                "relocation",
                "visa-process",
                "startup",
                "openbb"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/fully-free-financial-chatbot",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2023-05-09-fully-free-financial-chatbot.webp\"></p>\n<br>\n<p>The OpenBB Bot is a financial chatbot that allows you to access financial data from Discord or Telegram along with other users. From equity data to crypto, options, darkpool, economy and much more! Now available for free to registered users.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>We know the market conditions haven’t been great for anyone, particularly for investors. Instead of raising prices like trends, we have decided to offer our <a href=\"https://my.openbb.co/app/bot\" target=\"_blank\" rel=\"noopener noreferrer\">OpenBB Bot</a> individuals tier for free if you are a registered user.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"what-does-this-mean\">What does this mean<a href=\"https://didierlopes.com/blog/fully-free-financial-chatbot#what-does-this-mean\" class=\"hash-link\" aria-label=\"Direct link to What does this mean\" title=\"Direct link to What does this mean\">​</a></h2>\n<p>Registered users for OpenBB Bot will see the following changes:</p>\n<ul>\n<li>Users were limited to 100 options or dark pools commands per month. This limitation is completely removed.</li>\n<li>Users will no longer experience a 10s cooldown which means they can request investment research data sequentially and avoid breaking the conversation due to a delay imposed by the product</li>\n<li>Through our soon-to-be-announced new platform, you will be able to fully customize your charting style with up to 5 in chart technical indicators and 2 off charts. This is a big improvement over the 1 in chart and 1 off chart previously available.</li>\n<li>The number of custom alerts that the user can set for when certain threshold values are triggered has increased, from 3 to 10.</li>\n<li>Users can now set 10 watchlist tickers to pay close attention to and access data regarding them.</li>\n</ul>\n<p>Below is a video of what the OpenBB Bot is capable of:</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"1_d1vD4AkwpYk42tdbHuMupQ\" src=\"https://didierlopes.com/assets/images/2023-05-09-fully-free-financial-chatbot_1-f069a325b04c80fef360547afb1f1770.webp\" width=\"1004\" height=\"1263\" class=\"img_ev3q\"></p>\n<p>The interactive charts will open up within the <a href=\"https://my.openbb.co/\" target=\"_blank\" rel=\"noopener noreferrer\">OpenBB Hub</a> and in it you will be able to fully customize the technical analysis indicators that you see on the chart and even the candle chart color theme and type. A demo is shown below,</p>\n<div class=\"flex place-items-center justify-center items-center rounded-sm mx-auto\"><iframe src=\"https://www.youtube.com/embed/y2aYr0tXji4?si=VOV-G0Oc8INtm59Y\" width=\"800\" height=\"400\"></iframe></div>\n<br>\n<p>Like dozens of thousands of investors, join the OpenBB Hub so you can fully leverage the <a href=\"https://my.openbb.co/app/bot\" target=\"_blank\" rel=\"noopener noreferrer\">OpenBB Bot</a>.</p>\n<p>You can actually see how many users we have utilizing the bot on a daily basis on our <a href=\"https://openbb.co/company/open/bot\" target=\"_blank\" rel=\"noopener noreferrer\">/open page</a>.</p>\n<p>While others zig, we zag. Here’s the updated pricing:</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2023-05-09-fully-free-financial-chatbot_2-bd87201e9bf70791536078f5f7a4f909.webp\" width=\"1400\" height=\"933\" class=\"img_ev3q\"></p>\n<p>Looking forward to feedback!</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/fully-free-financial-chatbot",
            "title": "Fully free financial chatbot",
            "summary": "The OpenBB Bot is a financial chatbot that allows you to access financial data from Discord or Telegram along with other users. From equity data to crypto, options, darkpool, economy and much more! Now available for free to registered users.",
            "date_modified": "2023-05-09T00:00:00.000Z",
            "tags": [
                "openbb-bot",
                "financial-chatbot",
                "investment",
                "free",
                "discord",
                "telegram",
                "equity",
                "crypto",
                "options",
                "darkpool",
                "economy"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/free-investment-research-ecosystem-to-consistently-beat-the-market",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2023-05-05-free-investment-research-ecosystem-to-consistently-beat-the-market.webp\"></p>\n<br>\n<p>The OpenBB Hub is a comprehensive platform for managing all products, data, subscriptions, and content for users, aiming to empower investors globally with tools previously exclusive to institutions.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>The OpenBB Hub is the new one-stop-shop for managing all products, data, subscriptions, and content for users!</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"introduction\">Introduction<a href=\"https://didierlopes.com/blog/free-investment-research-ecosystem-to-consistently-beat-the-market#introduction\" class=\"hash-link\" aria-label=\"Direct link to Introduction\" title=\"Direct link to Introduction\">​</a></h2>\n<p>When we started this journey, we always wanted to empower investors across the globe to have access to tools previously only available to institutions.</p>\n<p>We started by building the <a href=\"https://my.openbb.co/app/terminal\" target=\"_blank\" rel=\"noopener noreferrer\">OpenBB Terminal</a> which is an open source investment research platform that users can customize as they see fit and build on top of.</p>\n<p>If you haven’t starred the repo, now is a good chance to do so <a href=\"https://github.com/OpenBB-finance/OpenBBTerminal\" target=\"_blank\" rel=\"noopener noreferrer\">here</a> ⭐️.</p>\n<p>Then, we wanted to address the social nature of investing. Instead of adding the chat functionality to OpenBB Terminal, we brought investment research data where these communities were already having fruitful discussions (Discord and Telegram). This makes much more sense from a user-convenience standpoint, and that’s how the OpenBB Bot was born. More information <a href=\"https://my.openbb.co/app/bot\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<p>As much customization as the OpenBB Terminal allowed, we didn’t give creators as much freedom as we could have since they would need to download the source code of the terminal in order to leverage our core.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2023-05-05-free-investment-research-ecosystem-to-consistently-beat-the-market_1-06ee26729dab4d315d065dae909f75a4.webp\" width=\"1400\" height=\"738\" class=\"img_ev3q\"></p>\n<p>But we we wanted to make this experience as seamless as possible so users could build on top of our foundation. Thus, we repurposed the core of the OpenBB Terminal into an OpenBB SDK that is “<em>pip installable</em>” from everywhere — <a href=\"https://pypi.org/project/openbb/\" target=\"_blank\" rel=\"noopener noreferrer\">OpenBB</a> . This means that all you need to have access to a universe of investment research data programmatically is python and running pip install openbb within a notebook.</p>\n<p>This was a big win since the community reaction was very positive and we are now seeing it adopted by investors, educational courses, and even content creators. So much that we even created a tab to keep track of these on our <a href=\"https://openbb.co/open\" target=\"_blank\" rel=\"noopener noreferrer\">/open page</a>.</p>\n<p>However, we focused too much on the products and didn’t slow down to think about the user experience utilizing multiple OpenBB products. This is where OpenBB Hub comes into play. <a href=\"https://my.openbb.co/\" target=\"_blank\" rel=\"noopener noreferrer\">OpenBB Hub</a> is the platform we use to interact with our community, push OpenBB content, allow product management, and much more.</p>\n<p>TL;DR:</p>\n<ul>\n<li>Allows to manage your OpenBB Terminal API keys, feature flags and settings. In addition, we allow users to save &amp; share their openbb script routines</li>\n<li>Allows access to the OpenBB Terminal installer new versions</li>\n<li>Allows access to the OpenBB Bot dashboard — which allows fully customization from a user perspective. This improves your experience by 10x when using OpenBB Bot on Telegram or Discord.</li>\n<li>Allows to sign-up for early waitlist of OpenBB Terminal Pro</li>\n</ul>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"openbb-hub---openbb-terminal\">OpenBB Hub - OpenBB Terminal<a href=\"https://didierlopes.com/blog/free-investment-research-ecosystem-to-consistently-beat-the-market#openbb-hub---openbb-terminal\" class=\"hash-link\" aria-label=\"Direct link to OpenBB Hub - OpenBB Terminal\" title=\"Direct link to OpenBB Hub - OpenBB Terminal\">​</a></h2>\n<p>Since the beginning users have installed the OpenBB Terminal in multiple desktops due to its free nature. The issue? The API key management was a pain since there was not a way to sync these across different machines. Until now.</p>\n<p>With <a href=\"https://my.openbb.co/\" target=\"_blank\" rel=\"noopener noreferrer\">OpenBB Hub</a> and using that account detail to log in the terminal, this problem gets fixed. Not only that, but users will benefit from default data sources, terminal color schema customization and even .openbb routines being manageable from Hub and more importantly accessible on a terminal instance as long as they login with their user details.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2023-05-05-free-investment-research-ecosystem-to-consistently-beat-the-market_2-c28b05aa6d945bedb4719ed145a2bf07.webp\" width=\"1400\" height=\"833\" class=\"img_ev3q\"></p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"openbb-hub---openbb-bot\">OpenBB Hub - OpenBB Bot<a href=\"https://didierlopes.com/blog/free-investment-research-ecosystem-to-consistently-beat-the-market#openbb-hub---openbb-bot\" class=\"hash-link\" aria-label=\"Direct link to OpenBB Hub - OpenBB Bot\" title=\"Direct link to OpenBB Hub - OpenBB Bot\">​</a></h2>\n<p>Today we are also announcing the OpenBB Bot will be fully free for individuals. All you have to do is to register for the <a href=\"https://my.openbb.co/\" target=\"_blank\" rel=\"noopener noreferrer\">OpenBB Hub</a>.</p>\n<p>For users that were already users of our OpenBB Bot, the only change on the platform is pricing and an increase push towards better documentation and more tutorials. This is an initiative that we are taking company-wide to focus on better documentation and more content to fully leverage our suite of products.</p>\n<p>OpenBB bot is critical to us as we work hard towards making a full ecosystem for investment research. And now you can access this experience for free, and share investment research data with your friends / colleagues.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2023-05-05-free-investment-research-ecosystem-to-consistently-beat-the-market_3-82a6c6cce7e25eec364075d5cb8d0c55.webp\" width=\"1400\" height=\"833\" class=\"img_ev3q\"></p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"openbb-hub---openbb-sdk\">OpenBB Hub - OpenBB SDK<a href=\"https://didierlopes.com/blog/free-investment-research-ecosystem-to-consistently-beat-the-market#openbb-hub---openbb-sdk\" class=\"hash-link\" aria-label=\"Direct link to OpenBB Hub - OpenBB SDK\" title=\"Direct link to OpenBB Hub - OpenBB SDK\">​</a></h2>\n<p>As the OpenBB SDK is in its core a pip installable package with its <a href=\"https://pypi.org/project/openbb/\" target=\"_blank\" rel=\"noopener noreferrer\">own page on PiPy</a> there aren’t a lot of functionalities that we can make available in this page. We allow the user to set their API keys similarly to what we do in the Terminal, to improve UX when utilizing the SDK.</p>\n<p>In addition, we are going to display open source projects built by the community that leverage our core so that they can serve as an inspiration to you. If you are working on something that uses OpenBB at its core, tag your GitHub repository with “openbb” and we’ll add you to the list of projects that rely on our foundation.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2023-05-05-free-investment-research-ecosystem-to-consistently-beat-the-market_4-7f85d569972f555fb6aed56d1cbae252.webp\" width=\"1400\" height=\"833\" class=\"img_ev3q\"></p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"openbb-hub---openbb-terminal-pro-waitlist\">OpenBB Hub - OpenBB Terminal Pro (waitlist)<a href=\"https://didierlopes.com/blog/free-investment-research-ecosystem-to-consistently-beat-the-market#openbb-hub---openbb-terminal-pro-waitlist\" class=\"hash-link\" aria-label=\"Direct link to OpenBB Hub - OpenBB Terminal Pro (waitlist)\" title=\"Direct link to OpenBB Hub - OpenBB Terminal Pro (waitlist)\">​</a></h2>\n<p>If all these features weren’t enough, we have decided to open the <a href=\"https://my.openbb.co/app/pro/early-access\" target=\"_blank\" rel=\"noopener noreferrer\">OpenBB Terminal Pro WAITLIST</a> for users who register on our OpenBB Hub.</p>\n<p>The OpenBB Terminal Pro is something that has been months in the works and is yet our most exciting product to date. We have been holding back on it because we believe this will change the way investors think about investing. This time we worked with design partners and had dozens of user interviews from financial professionals to understand their pain points and what role we could fill. So even being able to start creating a waitlist around it is something that the team is very excited about.</p>\n<p>We will gradually roll out the OpenBB Terminal Pro to a few users from the waitlist to get early feedback.</p>\n<p>If you are one of these, I look forward to onboarding you personally 🤝</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2023-05-05-free-investment-research-ecosystem-to-consistently-beat-the-market_5-2a16b1db1592d2fe462f0854d80f9ede.webp\" width=\"1400\" height=\"833\" class=\"img_ev3q\"></p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"final-thoughts\">Final thoughts<a href=\"https://didierlopes.com/blog/free-investment-research-ecosystem-to-consistently-beat-the-market#final-thoughts\" class=\"hash-link\" aria-label=\"Direct link to Final thoughts\" title=\"Direct link to Final thoughts\">​</a></h2>\n<p>Although OpenBB Hub is not a product per se, the amount of work that the team put together to make this happen is something nothing short of extraordinary. This was the first project where the entire team (~20 people from engineering, product, design and marketing) had to work together as whole.</p>\n<p>The OpenBB Terminal dashboard is completely new, the concept of login had to be invented and needed to function perfectly with the Hub. The SDK page is also new. The OpenBB Bot dashboard already existed, but we made the tier for individuals completely free, so we had to update it to reflect that big pricing change. And finally, we open the OpenBB Terminal Pro waitlist.</p>\n<p>The <a href=\"https://my.openbb.co/\" target=\"_blank\" rel=\"noopener noreferrer\">OpenBB Hub</a> is completely free.</p>\n<p>All you have to do is to register so we can know more information about yourself regarding your primary usage for our products (professional, academic, personal) — this allows us to understand what features to prioritize in the future and improve the quality of our products.</p>\n<p>In case you missed the webinar, you can view it below so that you are up-to-date with all the exciting new features that the team has released.</p>\n<div class=\"flex place-items-center justify-center items-center rounded-sm mx-auto\"><iframe src=\"https://www.youtube.com/embed/_4dQs_q_Jtk?si=76h-YFtiqkATHisF\" width=\"800\" height=\"400\"></iframe></div>\n<br><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/free-investment-research-ecosystem-to-consistently-beat-the-market",
            "title": "Free investment research ecosystem to consistently beat the market",
            "summary": "The OpenBB Hub is a comprehensive platform for managing all products, data, subscriptions, and content for users, aiming to empower investors globally with tools previously exclusive to institutions.",
            "date_modified": "2023-05-05T00:00:00.000Z",
            "tags": [
                "openbb",
                "investment-research",
                "openbb-terminal",
                "openbb-bot",
                "openbb-sdk",
                "openbb-hub"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/the-role-of-ai-and-openbb-in-the-future-of-investment-research",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2023-04-03-the-role-of-ai-and-openbb-in-the-future-of-investment-research.webp\"></p>\n<br>\n<p>How OpenBB can lead the future of finance using AI on top of an open source investment research platform.</p>\n<p>The open source code is available <a href=\"https://github.com/openbb-finance/OpenBBTerminal\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"introduction\">Introduction<a href=\"https://didierlopes.com/blog/the-role-of-ai-and-openbb-in-the-future-of-investment-research#introduction\" class=\"hash-link\" aria-label=\"Direct link to Introduction\" title=\"Direct link to Introduction\">​</a></h2>\n<p>This blogpost won't speak about what the OpenBB Terminal can offer today. Instead, we are going to share where we think AI can play a role in the future of investment research, and how through an open source platform, we can lead that wave.</p>\n<p>A lot of this blog is based on the fact that the OpenBB Terminal is an open source investment research platform, and therefore it's very relevant to read <a href=\"https://didierlopes.com/blog/why-the-need-for-an-open-source-investment-research-platform\">our blogpost about why we are open source</a>.</p>\n<p>Note: This blogpost will share several proof-of-concepts that are still within R&amp;D and are not yet ready for production. Also, this blogpost will assume that you are aware of LLMs such as ChatGPT and WhisperAI.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"chatgpt-as-the-interface\">ChatGPT as the interface<a href=\"https://didierlopes.com/blog/the-role-of-ai-and-openbb-in-the-future-of-investment-research#chatgpt-as-the-interface\" class=\"hash-link\" aria-label=\"Direct link to ChatGPT as the interface\" title=\"Direct link to ChatGPT as the interface\">​</a></h2>\n<p>An edge that incumbents have is the fact that they have been around for a very long time and spent a lot on educating users about their product. As a result, users are used to their platform. This makes it harder for users to switch to an unknown product, meaning they need to be 10x better than the competition for them to do so.</p>\n<p>However, what if there was no learning curve? What if you could use a product for the first time and know how to access all the information you wanted without spending any time reading the documentation? In essence, the educational incumbent advantage would become obsolete.</p>\n<p>With the new LLM advancements, such as ChatGPT. We are not far from this reality. Below is a proof-of-concept of what this could look like:</p>\n<div class=\"flex place-items-center justify-center items-center rounded-sm mx-auto\"><iframe src=\"https://www.youtube.com/embed/FeYgQxnF_VY?si=3ZuXnyrWdW4UkqQy\" width=\"800\" height=\"400\"></iframe></div>\n<p>Plus, if this is built on top of an open source project it means that the community can help in improving the model by providing more training data (e.g. provide a text as input and the corresponding command as output) or even confirm whether or not the chart that pops up was accurate.</p>\n<p>In addition, along with data sources you can imagine that the community could start contributing with new languages for the GPT model. This makes using a new investment research platform easy, but more importantly makes retrieving information much faster and efficient.</p>\n<p>The screenshot below shows that ChatGPT can accurately return the right OpenBB command when the user requests a certain type of data, as long as the model can be trained on our documentation:</p>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https://cdn-images-1.medium.com/max/1600/1*IWnSMNhHDyiulxri_hEB0g.webp\" alt=\"image\" class=\"img_ev3q\"></p>\n<p>EDIT: Bloomberg introduced <a href=\"https://openai.com/research/whisper\" target=\"_blank\" rel=\"noopener noreferrer\">BloombergGPT</a> last week, and the following screenshot is taken from their research paper which validates the argument above.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2023-04-03-the-role-of-ai-and-openbb-in-the-future-of-investment-research_1-10835aadf47f6a59764c019cdc8aedec.webp\" width=\"1222\" height=\"808\" class=\"img_ev3q\"></p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"whisperai-as-the-interface\">WhisperAI as the interface<a href=\"https://didierlopes.com/blog/the-role-of-ai-and-openbb-in-the-future-of-investment-research#whisperai-as-the-interface\" class=\"hash-link\" aria-label=\"Direct link to WhisperAI as the interface\" title=\"Direct link to WhisperAI as the interface\">​</a></h2>\n<p>If we go one step further, instead of relying on text as input, the platform could rely on voice. With models such as <a href=\"https://www.bloomberg.com/company/press/bloomberggpt-50-billion-parameter-llm-tuned-finance\" target=\"_blank\" rel=\"noopener noreferrer\">WhisperAI</a> we will be able to speak with the platform in order to retrieve financial data.</p>\n<p>Below is a proof-of-concept showing how you can retrieve this data through voice.</p>\n<div class=\"flex place-items-center justify-center items-center rounded-sm mx-auto\"><iframe src=\"https://www.youtube.com/embed/1CHti3nmWGY?si=yLF5AFHe91JFVgaS\" width=\"800\" height=\"400\"></iframe></div>\n<p>One of the advantages of an automatic speech recognition (ASR) system is the fact that it doesn't rely solely on english and therefore, it would welcome people from all over the world to interact with the platform. Note: WhisperAI is open source and you can find more information on it <a href=\"https://github.com/openai/whisper\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"gpt-to-build-investment-research-reports\">GPT to build investment research reports<a href=\"https://didierlopes.com/blog/the-role-of-ai-and-openbb-in-the-future-of-investment-research#gpt-to-build-investment-research-reports\" class=\"hash-link\" aria-label=\"Direct link to GPT to build investment research reports\" title=\"Direct link to GPT to build investment research reports\">​</a></h2>\n<p>One of the new features that was announced with the <a href=\"https://openbb.co/blog/openbb-terminal-2-acai\" target=\"_blank\" rel=\"noopener noreferrer\">OpenBB Terminal 2.0</a> was the automated reports generation that utilizes <a href=\"https://netflixtechblog.com/notebook-innovation-591ee3221233\" target=\"_blank\" rel=\"noopener noreferrer\">Netflix's papermill</a> to leverage jupyter notebook templates.</p>\n<div class=\"flex place-items-center justify-center items-center rounded-sm mx-auto\"><iframe src=\"https://www.youtube.com/embed/gHVyAZTampQ?si=s-4uIElohM-qzmNh\" width=\"800\" height=\"400\"></iframe></div>\n<p>As it stands creating one of these notebook templates requires some coding skills and reading <a href=\"https://docs.openbb.co/\" target=\"_blank\" rel=\"noopener noreferrer\">OpenBB documentation</a> to understand how to retrieve the data of interest providing the correct function and necessary arguments.</p>\n<p>But, for a second, imagine if you could build these notebook templates with almost no-code?</p>\n<p>The proof-of-concept below in combination with the automated report generation should allow you to further understand the breakthrough that we may accomplish in the future.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2023-04-03-the-role-of-ai-and-openbb-in-the-future-of-investment-research_2-e7f0448fa868ea4df5a563962da3d861.webp\" width=\"1400\" height=\"1204\" class=\"img_ev3q\"></p>\n<p>My prediction is that open source + AI will disrupt the financial sector in the upcoming years, and OpenBB will be leading that wave.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/the-role-of-ai-and-openbb-in-the-future-of-investment-research",
            "title": "The role of AI and OpenBB in the future of investment research",
            "summary": "How OpenBB can lead the future of finance using AI on top of an open source investment research platform.",
            "date_modified": "2023-04-03T00:00:00.000Z",
            "tags": [
                "openai",
                "future",
                "chatgpt",
                "discord"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/how-i-used-openai-api-to-improve-our-product-documentation",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2023-04-01-how-i-used-openai-api-to-improve-our-product-documentation.webp\"></p>\n<br>\n<p>In this blog post, I share how I used the OpenAI API to improve our product documentation. I used ChatGPT to generate more detailed descriptions for our OpenBB Bot Discord commands, making them more understandable for new users.</p>\n<p>The open source code is available <a href=\"https://github.com/DidierRLopes/improve-documentation-using-openai\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>The <a href=\"https://docs.openbb.co/bot/reference/discord\" target=\"_blank\" rel=\"noopener noreferrer\">documentation</a> of our free OpenBB Bot was pretty simplistic for most of the commands.</p>\n<p>For instance, the description for the command <code>/dp alldp</code> was: \"Last 15 Darkpool Trades\", as seen below:</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2023-04-01-how-i-used-openai-api-to-improve-our-product-documentation_1-a72b7c057f0e1c27960c355290df7813.webp\" width=\"1400\" height=\"659\" class=\"img_ev3q\"></p>\n<p>For more experienced traders, this may be enough. But for new users, these 4 words may not mean much.</p>\n<p>For context, this is the output that a user would get if running <code>/dp alldp</code> on our <a href=\"https://openbb.co/discord\" target=\"_blank\" rel=\"noopener noreferrer\">Discord server</a>.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2023-04-01-how-i-used-openai-api-to-improve-our-product-documentation_2-77de68e27200f905b3f9e6973eeac43f.webp\" width=\"1400\" height=\"889\" class=\"img_ev3q\"></p>\n<p>So I talked with someone in our team about improving the documentation. Not only for the new users that wanted to utilize our free product but also so that we could train our own LLM on this better dataset.</p>\n<p>Over the weekend I had the idea: What if I provided ChatGPT with the current description and an example of how to use the command and asked it to provide a more detailed description?</p>\n<p>So the next step was to try whether ChatGPT would indeed improve the current documentation.</p>\n<p>After a bit of prompt tweaking, I got a much better description than the one we currently had. See below:</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2023-04-01-how-i-used-openai-api-to-improve-our-product-documentation_3-58f95d977c4c46114a21a5eda1b3fea1.webp\" width=\"1400\" height=\"661\" class=\"img_ev3q\"></p>\n<p>The next step was rather straightforward. I created a script that iterated <a href=\"https://github.com/OpenBB-finance/OpenBBTerminal\" target=\"_blank\" rel=\"noopener noreferrer\">through all our OpenBB Bot Discord documentation</a> files and updated the old description with a more detailed one.</p>\n<p>This is the template prompt that I used:</p>\n<blockquote>\n<p><em>Context: You are a developer writing a detailed documentation for a function that allows the user to retrieve desc utilizing the command example how would you explain what this command does in a single paragraph”</em></p>\n</blockquote>\n<p>Where <strong>desc</strong> and <strong>example</strong> corresponds to the current description and example that each of our commands have, respectively.</p>\n<p>The results can be seen below (done on <a href=\"https://github.com/OpenBB-finance/OpenBBTerminal/pull/4657\" target=\"_blank\" rel=\"noopener noreferrer\">this PR</a>),</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2023-04-01-how-i-used-openai-api-to-improve-our-product-documentation_4-ef5db89e8ddb09d06c3b2fdce342c55d.webp\" width=\"1400\" height=\"387\" class=\"img_ev3q\"></p>\n<p>As usual, I open source the script <a href=\"https://github.com/DidierRLopes/improve-documentation-using-openai\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<p>The funny thing is that I used an LLM output to improve our documentation. And we may use this data to train our own LLM.</p>\n<p>LLM-ception?</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/how-i-used-openai-api-to-improve-our-product-documentation",
            "title": "How I Used OpenAI API to improve our product documentation",
            "summary": "In this blog post, I share how I used the OpenAI API to improve our product documentation. I used ChatGPT to generate more detailed descriptions for our OpenBB Bot Discord commands, making them more understandable for new users.",
            "date_modified": "2023-04-01T00:00:00.000Z",
            "tags": [
                "openai",
                "api",
                "chatgpt",
                "llm",
                "documentation",
                "automation",
                "openbb-bot",
                "discord"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/how-to-get-hired-by-an-exciting-tech-startup-in-2023",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2023-01-22-how-to-get-hired-by-an-exciting-tech-startup-in-2023.webp\"></p>\n<br>\n<p>The future is a strange place. We’re not entirely sure what it will look like, but we do know that it will be shaped by the choices we make today. And while I can’t tell you exactly how to get a job in 2023, I can help you set yourself up for success by showing you some of the best ways to build your career today.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>Everyone is doing the same hacker tests. Being good at interviews will no longer suffice to get a job in top tech company. Conventional CVs are too boring. Recruiters may like what they read, but this doesn’t make them think any further about a person and think “wow, we really need someone like them”.</p>\n<p>Ultimately, a CV cannot demonstrate creativity and in my opinion, to be a top engineer you need to be creative. Often there isn’t an easy straightforward solution and being creative is what distinguishes top tier engineers from medium. I wrote a post about this <a href=\"https://didierlopes.com/blog/stop-doing-your-cv-in-word-or-latex\">here</a>.</p>\n<p>Below I will let you know my views on what I would do to get a job at an exciting tech startup.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"work-on-open-source-projects\">Work on open source projects<a href=\"https://didierlopes.com/blog/how-to-get-hired-by-an-exciting-tech-startup-in-2023#work-on-open-source-projects\" class=\"hash-link\" aria-label=\"Direct link to Work on open source projects\" title=\"Direct link to Work on open source projects\">​</a></h2>\n<p>Open source is a great way to build your skills and get your name out there. It’s also a great way to make connections with other developers, which can lead to referrals and job opportunities. If you want to show that you’re a good engineer, open source is an excellent opportunity. This is because it allows you to demonstrate your problem-solving abilities, while also improving the codebase of a project that is potentially used by thousands of users — and because the project is open source, it never dies.</p>\n<p><strong>But which open source projects should you choose?</strong></p>\n<p>I’d say that there are two routes that you can take here. You can select the project based on your <strong>own use case</strong> or you can <strong>be strategic</strong> about it.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"own-use-case\">Own use case<a href=\"https://didierlopes.com/blog/how-to-get-hired-by-an-exciting-tech-startup-in-2023#own-use-case\" class=\"hash-link\" aria-label=\"Direct link to Own use case\" title=\"Direct link to Own use case\">​</a></h3>\n<p>Don’t overthink it. The world of software is built on top of open source. If it weren’t for open source, we would be living in the year 2000 or less. This means that your favorite apps are relying on open source projects, which you can be a part of!</p>\n<p>This means that you can:</p>\n<ul>\n<li>Contribute to an open source library that is used by a project that you like. E.g. someone from our team is a <a href=\"https://github.com/python/cpython\" target=\"_blank\" rel=\"noopener noreferrer\">cpython</a> contributor.</li>\n<li>Contribute to a product that you use that is Open Source. The advantage here is that you are able to literally customize the product that you are using.</li>\n</ul>\n<p>With Red Hat in the 90s this open source movement is starting to be a very hot topic. <a href=\"https://twitter.com/JosephJacks_\" target=\"_blank\" rel=\"noopener noreferrer\">Joseph Jacks</a> from OSS Capital is one of the best investors (if not the best) in this space. The chart below that he put together illustrates well the growth of open source (shared in <a href=\"https://twitter.com/JosephJacks_/status/1494840009882361859?s=20\" target=\"_blank\" rel=\"noopener noreferrer\">this tweet</a>)</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2023-01-22-how-to-get-hired-by-an-exciting-tech-startup-in-2023_1-2e7af0a5b5fbda8bdc1aeb512fe24a07.webp\" width=\"1400\" height=\"701\" class=\"img_ev3q\"></p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"strategic\">Strategic<a href=\"https://didierlopes.com/blog/how-to-get-hired-by-an-exciting-tech-startup-in-2023#strategic\" class=\"hash-link\" aria-label=\"Direct link to Strategic\" title=\"Direct link to Strategic\">​</a></h3>\n<p>If you’re reading this, there’s a good chance that you want to make a positive impact on the future of technology. If so, it can be helpful to consider how your work will affect the lives of others. Take some time and think about what kind of role you would like to play in shaping those futures — are you someone who wants to improve people’s physical well-being through health innovations? Or maybe achieve more efficient energy use through new technologies? This will help determine which companies or projects might be best suited for any given career path.</p>\n<p>Once you figure out what motivates you, select an industry where you wish to find a job.</p>\n<p>Then there are multiple paths that you can take:</p>\n<ul>\n<li>Look into the signals provided by top venture capital firms in that selected industry. I.e. see what open source companies are being backed in that space.</li>\n<li>Look into the developer engagement around the open source projects in that industry. You can not only use GitHub stars and forks, but you can use tools such as <a href=\"https://analyzemyrepo.com/analyze/OpenBB-finance/OpenBBTerminal\" target=\"_blank\" rel=\"noopener noreferrer\">https://analyzemyrepo.com</a> or <a href=\"https://ossinsight.io/\" target=\"_blank\" rel=\"noopener noreferrer\">https://ossinsight.io/</a></li>\n<li>Cold email VCs to ask them about which open source products they are excited about. I say VCs because often their job is to find these startups early, so usually they have more recent information. But talking with devs or listening to people that you respect in the industry is equally valid.</li>\n</ul>\n<p>Note: By being an early contributor of a promising open source startup, you can become a core maintainer of a project and even make it to the founding team. This is how I met James, OpenBB’s co-founder. He was an active developer in my own open source project, and I invited him to be part of the main maintainers of the project. When we built a company, he became a founding member.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"develop-your-own-open-source-project\">Develop your own open source project<a href=\"https://didierlopes.com/blog/how-to-get-hired-by-an-exciting-tech-startup-in-2023#develop-your-own-open-source-project\" class=\"hash-link\" aria-label=\"Direct link to Develop your own open source project\" title=\"Direct link to Develop your own open source project\">​</a></h2>\n<p>I strongly believe that being able to successfully build your own open source project is severely underrated. There are so many components that you need to get right from so many departments that it shows a lot about your strengths as an individual and a preview of the value you could add to the team.</p>\n<p>You may think that the only thing that you are demonstrating is your ability to write high-quality code since it will be open to the public. Well that’s wrong. Here is a non-exhaustive list of skills that you show off</p>\n<ul>\n<li>Solution to a real-world problem</li>\n<li>Design around the product</li>\n<li>User experience</li>\n<li>How you prioritize task and how fast you can ship high-quality code</li>\n<li>Interaction with others</li>\n<li>Marketing</li>\n<li>Listening to feedback from users</li>\n</ul>\n<p>This is what I did with OpenBB Terminal: <a href=\"https://github.com/OpenBB-finance/OpenBBTerminal\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/OpenBB-finance/OpenBBTerminal</a> and it has single handedly changed my life.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"conclusion\">Conclusion<a href=\"https://didierlopes.com/blog/how-to-get-hired-by-an-exciting-tech-startup-in-2023#conclusion\" class=\"hash-link\" aria-label=\"Direct link to Conclusion\" title=\"Direct link to Conclusion\">​</a></h2>\n<p>If you’re looking for a job in 2023, the best thing you can do is to contribute to/develop open source projects.</p>\n<p>You should be aware that you can also add value to an open source project by reporting bugs. You can even do more than just report a bug, but suggest a solution or workaround for the problem — this shows that not only are you paying attention to what’s going on around you, but also that you have some ideas about how things could be improved — a combination that any hiring manager would love!</p>\n<p>I hope you found this post insightful.</p>\n<p>Any feedback is welcome.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/how-to-get-hired-by-an-exciting-tech-startup-in-2023",
            "title": "How to get hired by an exciting tech startup in 2023",
            "summary": "The future is a strange place. We’re not entirely sure what it will look like, but we do know that it will be shaped by the choices we make today. And while I can’t tell you exactly how to get a job in 2023, I can help you set yourself up for success by showing you some of the best ways to build your career today.",
            "date_modified": "2023-01-22T00:00:00.000Z",
            "tags": [
                "career-advice",
                "tech-startups",
                "open-source",
                "job-hunting",
                "hiring",
                "recruiting",
                "software-engineering",
                "personal-branding"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/financial-chat-bots-are-underrated-and-heres-why",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2023-01-05-financial-chat-bots-are-underrated-and-heres-why.webp\"></p>\n<br>\n<p>In this blog post, we discuss the underrated potential of financial chat bots, our collaboration with OptionsFamBot, and why chat bots are becoming increasingly popular.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>At OpenBB, earlier this year we <a href=\"https://openbb.co/products/bot\" target=\"_blank\" rel=\"noopener noreferrer\">joined forces with OptionsFamBot</a>. This was a bot that had a reach of over 1 Million users on Discord.</p>\n<p>Today, <a href=\"https://openbb.co/products/bot\" target=\"_blank\" rel=\"noopener noreferrer\">OpenBB Bot</a> is one of our more powerful products and I still think a lot of people are sleeping on it.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"what-is-a-chatting-bot-platform\">What is a chatting bot platform?<a href=\"https://didierlopes.com/blog/financial-chat-bots-are-underrated-and-heres-why#what-is-a-chatting-bot-platform\" class=\"hash-link\" aria-label=\"Direct link to What is a chatting bot platform?\" title=\"Direct link to What is a chatting bot platform?\">​</a></h3>\n<p>According to <a href=\"https://chat.openai.com/chat\" target=\"_blank\" rel=\"noopener noreferrer\">ChatGPT</a>:</p>\n<blockquote>\n<p><em>“A chatbot platform is a software service or tool that enables the creation, management, and deployment of chatbots. These platforms typically provide a variety of tools and features for building, testing, and deploying chatbots, as well as options for integrating chatbots with other systems or services. Some chatbot platforms are designed to support the development of chatbots for specific industries or use cases, such as customer service, e-commerce, or marketing. Others are more general purpose, and can be used to build chatbots for a wide range of applications.”</em></p>\n</blockquote>\n<br>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"why-are-chat-bots-not-engaging\">Why are chat bots not engaging?<a href=\"https://didierlopes.com/blog/financial-chat-bots-are-underrated-and-heres-why#why-are-chat-bots-not-engaging\" class=\"hash-link\" aria-label=\"Direct link to Why are chat bots not engaging?\" title=\"Direct link to Why are chat bots not engaging?\">​</a></h3>\n<p>I believe that one of the reasons for this is because people usually associate chatbots with customer service or marketing. Not as a finalized product but as a feature.</p>\n<p>If I ask ChatGPT about this, the main reasons are: Lack of personalized conversation, limited capabilities, poor design and high error rate.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2023-01-05-financial-chat-bots-are-underrated-and-heres-why_1-0b632aaa3e3ac5ce8c2246c36a02f79a.webp\" width=\"1400\" height=\"994\" class=\"img_ev3q\"></p>\n<p>But wait.. ChatGPT is <strong>LITERALLY</strong> a chat bot. Everything happens through a chat interface, which shows that you can build a successful product as a bot, as long as it adds enough value to the user.</p>\n<p>One could argue that ChatGPT is not done in an established chatting platform, and that is <strong>partially true</strong>. The reason I say partially is because ChatGPT has an API, so developers can use it to develop their own chatting bots and deploy it in whatever chatting app they are interested in.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"examples-of-good-chatting-platforms\">Examples of good chatting platforms<a href=\"https://didierlopes.com/blog/financial-chat-bots-are-underrated-and-heres-why#examples-of-good-chatting-platforms\" class=\"hash-link\" aria-label=\"Direct link to Examples of good chatting platforms\" title=\"Direct link to Examples of good chatting platforms\">​</a></h2>\n<p>I believe that Discord is in the forefront here due to: Free, easy to use, allows customizing servers with roles/channels/permissions, high-quality voice chat, strong communities.</p>\n<p>A testament to this is the fact that <a href=\"https://midjourney.com/\" target=\"_blank\" rel=\"noopener noreferrer\">midjourney</a> has built a successful chat bot that generates images from text prompts using AI, <strong>SOLELY</strong> relying on Discord. If you go into their website, the button “<strong>Join the Beta</strong>” takes you to their Discord server which has over <strong>7 million users</strong>!</p>\n<p>As far as I know, this is the only example of a company that distributes their product solely through a chatting platform in a successful way.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2023-01-05-financial-chat-bots-are-underrated-and-heres-why_2-9a2c7ad2e5b674a3f670b8e9fda216ca.webp\" width=\"1400\" height=\"321\" class=\"img_ev3q\"></p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"why-are-chat-bots-getting-more-popular\">Why are chat bots getting more popular?<a href=\"https://didierlopes.com/blog/financial-chat-bots-are-underrated-and-heres-why#why-are-chat-bots-getting-more-popular\" class=\"hash-link\" aria-label=\"Direct link to Why are chat bots getting more popular?\" title=\"Direct link to Why are chat bots getting more popular?\">​</a></h2>\n<p>In my opinion, there are a few factors why chat bots are becoming more popular:</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"interactivity\">Interactivity<a href=\"https://didierlopes.com/blog/financial-chat-bots-are-underrated-and-heres-why#interactivity\" class=\"hash-link\" aria-label=\"Direct link to Interactivity\" title=\"Direct link to Interactivity\">​</a></h3>\n<p>The bots are becoming more interactive, almost working like an application within a chatting platform.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"interactivity\" src=\"https://didierlopes.com/assets/images/2023-01-05-financial-chat-bots-are-underrated-and-heres-why_3-5f28334991537af07bad486fdfa84435.webp\" width=\"2120\" height=\"1729\" class=\"img_ev3q\"></p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"speed\">Speed<a href=\"https://didierlopes.com/blog/financial-chat-bots-are-underrated-and-heres-why#speed\" class=\"hash-link\" aria-label=\"Direct link to Speed\" title=\"Direct link to Speed\">​</a></h3>\n<p>The speed of interaction is increasing over time, making the experience more seamless.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"speed\" src=\"https://didierlopes.com/assets/images/2023-01-05-financial-chat-bots-are-underrated-and-heres-why_4-d78896d308b0f0156068e11a2e5cd159.webp\" width=\"1720\" height=\"863\" class=\"img_ev3q\"></p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"customization\">Customization<a href=\"https://didierlopes.com/blog/financial-chat-bots-are-underrated-and-heres-why#customization\" class=\"hash-link\" aria-label=\"Direct link to Customization\" title=\"Direct link to Customization\">​</a></h3>\n<p>The level of customization allowed for these bots keeps on increasing.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"customization\" src=\"https://didierlopes.com/assets/images/2023-01-05-financial-chat-bots-are-underrated-and-heres-why_5-a1f3d286b99fc9826cfe79104db1ee6d.webp\" width=\"1720\" height=\"863\" class=\"img_ev3q\"></p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"automation\">Automation<a href=\"https://didierlopes.com/blog/financial-chat-bots-are-underrated-and-heres-why#automation\" class=\"hash-link\" aria-label=\"Direct link to Automation\" title=\"Direct link to Automation\">​</a></h3>\n<p>You are starting to be able to create automated workflows. Not only for you, but for entire communities.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"automation\" src=\"https://didierlopes.com/assets/images/2023-01-05-financial-chat-bots-are-underrated-and-heres-why_6-5847a3ebb3cdf0c0eb5643030a0e3764.webp\" width=\"1695\" height=\"863\" class=\"img_ev3q\"></p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"notifications\">Notifications<a href=\"https://didierlopes.com/blog/financial-chat-bots-are-underrated-and-heres-why#notifications\" class=\"hash-link\" aria-label=\"Direct link to Notifications\" title=\"Direct link to Notifications\">​</a></h3>\n<p>It has notification features that can ping you similarly as if a friend sent you a message.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"notifications\" src=\"https://didierlopes.com/assets/images/2023-01-05-financial-chat-bots-are-underrated-and-heres-why_7-b31c8830c9983089832182a7d6c50d58.webp\" width=\"2120\" height=\"1728\" class=\"img_ev3q\"></p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"monetization\">Monetization<a href=\"https://didierlopes.com/blog/financial-chat-bots-are-underrated-and-heres-why#monetization\" class=\"hash-link\" aria-label=\"Direct link to Monetization\" title=\"Direct link to Monetization\">​</a></h3>\n<p>You are going to start to be able to monetize products through it.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"monetization\" src=\"https://didierlopes.com/assets/images/2023-01-05-financial-chat-bots-are-underrated-and-heres-why_8-a55afc36e6bb205f1964fcc9b3d10bb9.webp\" width=\"1695\" height=\"863\" class=\"img_ev3q\"></p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"community\">Community<a href=\"https://didierlopes.com/blog/financial-chat-bots-are-underrated-and-heres-why#community\" class=\"hash-link\" aria-label=\"Direct link to Community\" title=\"Direct link to Community\">​</a></h3>\n<p>You can use it within a server with friends/colleagues, and unlock a better user experience.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"community\" src=\"https://didierlopes.com/assets/images/2023-01-05-financial-chat-bots-are-underrated-and-heres-why_9-6884a91772087611a0be9cc0249d45ca.webp\" width=\"1030\" height=\"784\" class=\"img_ev3q\"></p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"standardization\">Standardization<a href=\"https://didierlopes.com/blog/financial-chat-bots-are-underrated-and-heres-why#standardization\" class=\"hash-link\" aria-label=\"Direct link to Standardization\" title=\"Direct link to Standardization\">​</a></h3>\n<p>The product can work similarly on multiple chatting platforms. By keeping the same method of interaction / commands, the user is allowed to pick their favourite chatting platform or even use it in more than 1.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"standardization\" src=\"https://didierlopes.com/assets/images/2023-01-05-financial-chat-bots-are-underrated-and-heres-why_10-7579e6e32d1d36dda6b810d3be6c828c.webp\" width=\"1120\" height=\"610\" class=\"img_ev3q\"></p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"accessibility\">Accessibility<a href=\"https://didierlopes.com/blog/financial-chat-bots-are-underrated-and-heres-why#accessibility\" class=\"hash-link\" aria-label=\"Direct link to Accessibility\" title=\"Direct link to Accessibility\">​</a></h3>\n<p>These chatting platforms are developed for all devices and operating systems, making it a very powerful distribution system.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"last\" src=\"https://didierlopes.com/assets/images/2023-01-05-financial-chat-bots-are-underrated-and-heres-why_11-9a4a84fc3e4e2dc6e1c0cd31b8a1bb9b.webp\" width=\"946\" height=\"2048\" class=\"img_ev3q\"></p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"why-finance\">Why Finance?<a href=\"https://didierlopes.com/blog/financial-chat-bots-are-underrated-and-heres-why#why-finance\" class=\"hash-link\" aria-label=\"Direct link to Why Finance?\" title=\"Direct link to Why Finance?\">​</a></h2>\n<p>I’ve spoke with over 100 people in the financial world in 2022. Over 50 are Bloomberg users. From those, 90% agree that their chatting feature is the most attractive feature — some of them going further and saying that that is the reason why they pay for it.</p>\n<p>But what if you didn’t need to pay $26 k / year for such feature. What if you could pay to have access to servers with big names in the industry? Or what if you could create your own servers? What if while you were talking with Cathie Wood about ARK performance, you could also access financial data from ARK to back up your arguments? All this while not leaving the chat.</p>\n<p>This is the reason why I believe that financial chatting bots will become popular in 2023. And <a href=\"https://openbb.co/products/bot\" target=\"_blank\" rel=\"noopener noreferrer\">OpenBB Bot</a> will be leading that wave.</p>\n<p>Try it out for free on <a href=\"https://openbb.co/discord\" target=\"_blank\" rel=\"noopener noreferrer\">OpenBB Discord server</a> by using a command such as <code>/chart TSLA</code> and let me know what you think.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/financial-chat-bots-are-underrated-and-heres-why",
            "title": "Financial chat bots are underrated, and here’s why.",
            "summary": "In this blog post, we discuss the underrated potential of financial chat bots, our collaboration with OptionsFamBot, and why chat bots are becoming increasingly popular.",
            "date_modified": "2023-01-05T00:00:00.000Z",
            "tags": [
                "chatbots",
                "finance",
                "ai",
                "discord",
                "openbb",
                "optionsfambot"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/firing-sucks-how-to-avoid-doing-so-by-hiring-a-players",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2023-01-02-firing-sucks-how-to-avoid-doing-so-by-hiring-a-players.webp\"></p>\n<br>\n<p>Firing is tough. This blogpost discusses how to avoid it by hiring A players, improving the hiring process, and understanding the importance of a scorecard in recruitment.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>In 2022, <a href=\"http://openbb.co/\" target=\"_blank\" rel=\"noopener noreferrer\">OpenBB</a> grew to 20 people. But amongst all of our hiring, we also had to let some people go.</p>\n<p>Before 2022, I had never fired anyone in my life but in my new role, I had to learn how to do it. If you’re a manager, you know that this is the hardest part of the job.</p>\n<p>Having that said, I wanted to use my Christmas holidays to understand how we can avoid letting people go. For this, I needed to start from the beginning and improve our overall hiring process.</p>\n<p>This blogpost will be highly based on the book <strong>“Who: The A Method for Hiring” by Geoff Smart and Randy Street</strong>, which I highly recommend.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"a-method-for-hiring\">A method for hiring<a href=\"https://didierlopes.com/blog/firing-sucks-how-to-avoid-doing-so-by-hiring-a-players#a-method-for-hiring\" class=\"hash-link\" aria-label=\"Direct link to A method for hiring\" title=\"Direct link to A method for hiring\">​</a></h2>\n<p>What is an A player? _A candidate who has at least a 90 percent chance of achieving a set of outcomes that only the top 10 percent of possible candidates could achieve.</p>\n<p>In this post, I will go over the steps to get an A team.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"data:image/webp;base64,UklGRsoGAABXRUJQVlA4IL4GAAAwNQCdASrSAPAAPjEYiUMiIaEWaYxQIAMEtLdwtdiN+bH597N/9r0e/tbK/q19Sbov7SfgB+XbhX8MPI7qifwg8WuQP/CP0D+Rf/1/8A8mj0e8gD2cP0L/A8elALeKhnw1QtWuJBa7dnpzQZnEOaagkWMQCT5tgqqRzaECEog17jhNHtD/pp0bQhs9Lp9Z0yPkwlQ257km1wwnNBn/kqYyfidcnOfjSFml/JfpyyujbMBD6sPRsr30cJ6czLODeERXOHZAQDqfNSVkrHhskF/w0W5cmzKcE985oM/mUHnT5u5j1ODChh2U/7vVDutIut4+JyLbN0xyhDRw2Q8p2fdEQpYH+e7zbK5Ebq7I84Sf0sowkFMFCCFbjgbaNP4zB3vGBrQ/FVPFmN9b4zCR37bRUofaECf2OyZxsKGNJoObIBN7DHwYEth4l7bwrrw1sLaCRTis+a17waGov1A36lLIdoQ4+x6USTSHN9Alw9qT8c3OESn3mFHVUOcU7VuIOatAMdorLMAbR1WUypQEaHIHlBlreB6VmQZ8vhIOqh8O0V/CAKb+ch6O+9es+LtQw9nkgAD+/2g/ywV56j8IRJUn7yvpXAsZjVca7cXKUq2wRcMDdQtRO/MgOXg3TbtkoXQKyFMxA8N9R6D/OVQrYW69mYoWjJfNKjHUolKHXDlW7uHkaujCWPzxnrZcKP8DTAbnNRFmEWv+feSLy/fT/1VDF36Gf79vxBvIWm4rDUOPyD1taM6uScmkGBbEjJ0riODL6lMh9XlCLaUxfDzyqq4sBYSHRqctS7j4yq4FzEDYt7kf6vHW40a2EJ8sLADw9HVwL8Zs+bjF3ROXhEKXkPkeK5JDuK/YEyT+U7Omjp7aqY2kKLsf+6BVMlFlRUUl8rszyygXdGF8egaBKiKZrlQ8cEIe3qjTOv8E/D962aeoI9Hx/inw1SnfNdttdVgkH8rqCuU9ovOnIdBrLXyT4ooukhDn7v+CK5dBnFntrArV1QsarbZF34Oymv/y76eNlsN6Sa5+dXskyrTq/Sf9wBRXpvB9VpzReaylfyNgmEzcibHjbtwh3/Rm9nuRibJ4LvDdE1lBtMIatcxPeEZ/v6eWD9aOceG/e6DGATWTRT9UuomZs2On/hkYJR2tvQqudezojWLR92Tzg49uoXXA9GTtzrzE84IdCha4peRWRkXMEpG1EPXHevA+oREtK6mtVH5Vhb6nQ/Kgu64hnrK6oVOTC7+zY0li8KFztVeLz7QGHHDCo8QBEQSLMXN6Yr/vMzeNm5QpuUTC/ZSgDzni3RJ1OhbzUgZ8pRTQ5L5W8V2yyUbiO4yNQlrkpLCxR3KxF3unVPSSd/DKLkLrmux4uYJasx7rB4euc94H1flymKCuO2CYn8hlv6muI5F816P5mQVMiBUgCBc62KpD9Pj/tp0/PrN5o2LRS98BBKAIPAb4oc5kmcOVJ+d2Dqk5CoZbG5TByp+fv+fx0TCTPy/izObzLHwOAhwMa6NleYcwO0zNrb/UwhbtTzzHzHDsBEI6vBVFi2n/qi0jYUENRSQXKuVJpmCdRf2gn+nFPsKjqnwCE71gC7mKQv4HuRtVEiE1+huZ4G9rh0OqM3CoL0CWWmL5LgQbZfq92usdd4xaRFjeiq49gaslct11syTCKLXDZBrjdp2hnMDjEZZtT319DGdgIOv2m+/T6T/7g2GTwH24nuCyBlMhJZ8Z7MmE6tB1BIGRMHsESalRrM1IuP1DP6duou0TFfE9H1P/nYfXK+F1Ql1s+reMOu+rum0MuLu2XE9GaLDA7I0zHg9XQPVlsbMiilkK1rHS98F4z4wDjtjKF90HyaczY0DridRAF5u/OrHnjYdclAvbC59u5bOWthIJ54VMjJ5NLhJcwnYiUF/i3M784NwAePKHIYBP+demzw4RDOjJWkfT41N2phMiQca4kcNLiVwZdNu2F+pFv2shYFTYhsA/v/Gm0MdbDNF0IVG5NqGDupvExIDjRHrFzNSMGEbJRJ3eYeNlf4QgeajY3oQf1EYk/2K3capGBrtg39uuDSVx1ub3ZqH6hkeojzLS5t34Jo0O5TXoVm5OoWr41IEIR414DTfSmYI0U9CvSmE2hzBOqyDXu+MTFTGTHOB2enZ/CNr8zHP8Yis0MY+c/6jhS1/QeQtDpPPOEsaQKruYv9J4qawPZdrAo6CWNoAuaYObQSLYmkq6O3uuX1/qma50kFQb9/9VvB6aHFFOwIEVxgfRkZ541gLaCyvbJIBHbCOcFByX6XE3edR7+oBsKDcljPAZ5Vk5cFgAAAAA\" width=\"210\" height=\"240\" class=\"img_ev3q\"></p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"scorecard\">Scorecard<a href=\"https://didierlopes.com/blog/firing-sucks-how-to-avoid-doing-so-by-hiring-a-players#scorecard\" class=\"hash-link\" aria-label=\"Direct link to Scorecard\" title=\"Direct link to Scorecard\">​</a></h2>\n<p>This is a document that describes the mission for the position, outcomes that must be accomplished, and competencies that fit with both the company culture and the role.</p>\n<p>This is an example of what a scorecard should look like:</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2023-01-02-firing-sucks-how-to-avoid-doing-so-by-hiring-a-players_2-9e88bcfb29890af50f5c5b2f209e14df.webp\" width=\"638\" height=\"851\" class=\"img_ev3q\"></p>\n<p>Let’s go through each of the sections in this document.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"mission\">Mission<a href=\"https://didierlopes.com/blog/firing-sucks-how-to-avoid-doing-so-by-hiring-a-players#mission\" class=\"hash-link\" aria-label=\"Direct link to Mission\" title=\"Direct link to Mission\">​</a></h3>\n<p>The mission is an executive summary of the job’s core purpose. It boils the job down to its essence so everybody understands why you need to hire someone in this role.</p>\n<p>The book talks about how you should avoid hiring a generalist. In my opinion, it depends on the stage of the company. At OpenBB, we are able to ship fast with a small team because we have a lot of generalists that are A players. However, finding a generalist A player is a much harder task than finding an A player specialist. Here, we benefit from having an open source project, since we get to build with candidates before we hire them.</p>\n<p><strong>How to:</strong> <em>Develop a short statement of one to five sentences that describe why a role exists.</em></p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"outcomes\">Outcomes<a href=\"https://didierlopes.com/blog/firing-sucks-how-to-avoid-doing-so-by-hiring-a-players#outcomes\" class=\"hash-link\" aria-label=\"Direct link to Outcomes\" title=\"Direct link to Outcomes\">​</a></h3>\n<p>Describes what a person needs to accomplish in a role.</p>\n<blockquote>\n<p><em>“While typical job descriptions break down because they focus on activities, or a list of things a person will be doing, scorecards succeed because they focus on outcomes, or what a person must get done.”</em></p>\n</blockquote>\n<br>\n<p><strong>How to:</strong> <em>Develop 3 to 8 specific objective outcomes that a person must accomplish to achieve an A performance, ranked by order of importance.</em></p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"competencies\">Competencies<a href=\"https://didierlopes.com/blog/firing-sucks-how-to-avoid-doing-so-by-hiring-a-players#competencies\" class=\"hash-link\" aria-label=\"Direct link to Competencies\" title=\"Direct link to Competencies\">​</a></h3>\n<p>Define how you expect a new hire to operate in the fulfilment of the job and how they can achieve their objectives. What competencies really count?</p>\n<h4 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"ensure-behavioural-fit\">Ensure behavioural fit<a href=\"https://didierlopes.com/blog/firing-sucks-how-to-avoid-doing-so-by-hiring-a-players#ensure-behavioural-fit\" class=\"hash-link\" aria-label=\"Direct link to Ensure behavioural fit\" title=\"Direct link to Ensure behavioural fit\">​</a></h4>\n<p>Critical competencies for A players are: Efficiency, honesty/integrity, organization, aggressiveness, follow-through, intelligence, analytical skills, attention to detail, persistence, proactivity.</p>\n<p>Others may include: Ability to hire A players, ability to develop people, flexibility/adaptability, calm under pressure, strategic thinking/visioning, creativity/innovation, enthusiasm, work ethic, high standards, listening skills, openness. to criticism and ideas, communications, team work and persuasion.</p>\n<h4 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"ensure-organizational-fit\">Ensure organizational fit<a href=\"https://didierlopes.com/blog/firing-sucks-how-to-avoid-doing-so-by-hiring-a-players#ensure-organizational-fit\" class=\"hash-link\" aria-label=\"Direct link to Ensure organizational fit\" title=\"Direct link to Ensure organizational fit\">​</a></h4>\n<p>Evaluating cultural fit begins with evaluating your company’s values against the ones of the candidate.</p>\n<p>Recently, at OpenBB, I asked everyone to share with me a list of values that we currently had and they were proud of, and/or values that they would like to use instead. In a startup, where the pace is incredibly fast and the team is in constant change, I strongly believe values change over time. So I looked at everyone’s inputs, and summarized them into the following OpenBB values: <strong>Autonomy and Ownership, Innovation and Excellence, Transparent and Trustworthy, Diversity and Inclusion, Purpose and Passion, User Focused and Community Oriented.</strong></p>\n<p><strong>How to:</strong> <em>Identify as many role-based competencies that you think are appropriate to describe the behaviors that someone must demonstrate to achieve the outcomes. Next, identify 5 to 8 competencies that describe your culture and place those on every scorecard.</em></p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"from-scorecard-to-strategy\">From scorecard to strategy<a href=\"https://didierlopes.com/blog/firing-sucks-how-to-avoid-doing-so-by-hiring-a-players#from-scorecard-to-strategy\" class=\"hash-link\" aria-label=\"Direct link to From scorecard to strategy\" title=\"Direct link to From scorecard to strategy\">​</a></h3>\n<p>The beauty of a document like this is that they become the blueprint that links the theory of strategy to the reality of execution. They translate your business plans into role-by-role outcomes, create alignment among your team, unify your culture and ensure people understand your expectations.</p>\n<p>In addition, they allow you to monitor employee progress over time in your annual review system and to rate your team as part of their talent review progress.</p>\n<p><strong>How to:</strong> <em>Pressure-test your scorecard by comparing it with the business plan and scorecards of the people who will interface with the role. Ensure that there is consistency and alignment. Then share the scorecard with relevant parties, including peers and recruiters.</em></p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"source\">Source<a href=\"https://didierlopes.com/blog/firing-sucks-how-to-avoid-doing-so-by-hiring-a-players#source\" class=\"hash-link\" aria-label=\"Direct link to Source\" title=\"Direct link to Source\">​</a></h2>\n<p>Systematic sourcing before you have slots to fill ensures you have high-quality candidates waiting when you need them.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"referrals-from-your-professional-and-personal-networks\">Referrals from your professional and personal networks<a href=\"https://didierlopes.com/blog/firing-sucks-how-to-avoid-doing-so-by-hiring-a-players#referrals-from-your-professional-and-personal-networks\" class=\"hash-link\" aria-label=\"Direct link to Referrals from your professional and personal networks\" title=\"Direct link to Referrals from your professional and personal networks\">​</a></h3>\n<p>Create a list of the ten most talented people you know and commit to speaking with at least one of them per week for the next ten weeks. At the end of each conversation ask “Who are the most talented people you know?”. Continue to build your list and continue to talk with at least one person per week. “<em>Of all the ways to source candidates, the number one method is to ask for referrals from your personal and professional networks</em>”.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"referrals-from-your-employees\">Referrals from your employees<a href=\"https://didierlopes.com/blog/firing-sucks-how-to-avoid-doing-so-by-hiring-a-players#referrals-from-your-employees\" class=\"hash-link\" aria-label=\"Direct link to Referrals from your employees\" title=\"Direct link to Referrals from your employees\">​</a></h3>\n<p>Add sourcing as an outcome on every scorecard for your team. Encourage employees to ask people in their networks. Offer a referral bonus. In-house referrals often provide better-targeted sourcing, this is because employees already know our needs and culture.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"deputizing-friends-of-the-firm\">Deputizing friends of the firm<a href=\"https://didierlopes.com/blog/firing-sucks-how-to-avoid-doing-so-by-hiring-a-players#deputizing-friends-of-the-firm\" class=\"hash-link\" aria-label=\"Direct link to Deputizing friends of the firm\" title=\"Direct link to Deputizing friends of the firm\">​</a></h3>\n<p>Consider offering a referral bounty to select friends of the firm. It could be as inexpensive as merchandise or as expensive as a significant cash bonus. When talking with someone new at a party or a VC, always ask “<em>who do you know who might be a good fit for my company?</em>”</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"sourcing-system\">Sourcing system<a href=\"https://didierlopes.com/blog/firing-sucks-how-to-avoid-doing-so-by-hiring-a-players#sourcing-system\" class=\"hash-link\" aria-label=\"Direct link to Sourcing system\" title=\"Direct link to Sourcing system\">​</a></h3>\n<p>Create a system that (1) captures the names and the contact information on everybody you source and (2) schedules weekly time on your calendar to follow up. Try to spend 30 minute every week sending messages or having calls with candidates from this database of A players.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"hiring-external-recruiters-or-hiring-recruiting-researchers\">Hiring external recruiters or hiring recruiting researchers<a href=\"https://didierlopes.com/blog/firing-sucks-how-to-avoid-doing-so-by-hiring-a-players#hiring-external-recruiters-or-hiring-recruiting-researchers\" class=\"hash-link\" aria-label=\"Direct link to Hiring external recruiters or hiring recruiting researchers\" title=\"Direct link to Hiring external recruiters or hiring recruiting researchers\">​</a></h3>\n<p>The book speaks about both, but from my experience of having an open company with an exciting mission that builds in public, these have not been relevant to us yet.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"select\">Select<a href=\"https://didierlopes.com/blog/firing-sucks-how-to-avoid-doing-so-by-hiring-a-players#select\" class=\"hash-link\" aria-label=\"Direct link to Select\" title=\"Direct link to Select\">​</a></h2>\n<p>Create a series of structured interviews which build on each other so you can rate your scorecard.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"screening-interview\">Screening Interview<a href=\"https://didierlopes.com/blog/firing-sucks-how-to-avoid-doing-so-by-hiring-a-players#screening-interview\" class=\"hash-link\" aria-label=\"Direct link to Screening Interview\" title=\"Direct link to Screening Interview\">​</a></h3>\n<p>Short, phone-based interview designed to clear out B and C players from your roster of candidates.</p>\n<ol>\n<li>\n<p><strong>What are your career goals?</strong> If no goals echo your own website goals, screen them out. Ideally candidate will speak with passion and energy about their goals which are aligned with the role.</p>\n</li>\n<li>\n<p><strong>What are you really good at professionally?</strong> Make sure that with the list of strengths, there are always examples to backup the claim. Ensure that those strengths are relevant to the competencies required in the scorecard, if not, screen them out.</p>\n</li>\n<li>\n<p><strong>What are you not good at or not interested in doing professionally?</strong> Ignore strengths disguised as weakness. Ask again “what are you really not good at or not interested in doing?”, talented people will catch the hint. If you’re still struggling to get a proper answer, put the fear of a reference check into the person — “if you advance to the next step in our process, we will ask for your help in setting up some references. (…) What would these references say are something things you are not good at or not interested in?”</p>\n</li>\n<li>\n<p><strong>Who were your last five bosses, and what would they each rate your performance on a scale of 1–10 WHEN we talk to them?</strong> The word ‘when’ is the key to unlock the truth. A rating of 7 is neutral, we are looking for 8 and above. After the rating answer always press for details.</p>\n</li>\n</ol>\n<br>\n<p>If you are happy with the interview so far, conclude the call by offering the candidate an opportunity to ask questions. Otherwise just thank them for their time.</p>\n<p><strong>Tips:</strong></p>\n<ul>\n<li>Always compare the person’s strengths with the ones on the scorecard.</li>\n<li>When in doubt, there’s no doubt. You need to have the feeling that you have found the one.</li>\n<li>Get curious: What, How, Tell me more. Keep using this framework until you are clear about what the person is really saying.</li>\n<li>Hit the gong fast. If an answer automatically rules out a candidate, just end up the interview earlier and use your precious time to focus on A players.</li>\n</ul>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"who-to-interview\">Who to Interview<a href=\"https://didierlopes.com/blog/firing-sucks-how-to-avoid-doing-so-by-hiring-a-players#who-to-interview\" class=\"hash-link\" aria-label=\"Direct link to Who to Interview\" title=\"Direct link to Who to Interview\">​</a></h3>\n<p>Chronological walk-through of a person’s career.</p>\n<p>You can begin by asking about the highs and lows of a person’s educational experience to gain insight into their background. After this, ask them 5 simple questions for each job they had in the past.</p>\n<h4 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"what-were-you-hired-to-do\">What were you hired to do?<a href=\"https://didierlopes.com/blog/firing-sucks-how-to-avoid-doing-so-by-hiring-a-players#what-were-you-hired-to-do\" class=\"hash-link\" aria-label=\"Direct link to What were you hired to do?\" title=\"Direct link to What were you hired to do?\">​</a></h4>\n<p>You are trying to discover what their scorecard might have been if they had one for that role. Ask them “how was your success measured in the role? What was the mission and key outcomes? What competencies mattered?”.</p>\n<h4 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"what-accomplishments-are-you-most-proud-of\">What accomplishments are you most proud of?<a href=\"https://didierlopes.com/blog/firing-sucks-how-to-avoid-doing-so-by-hiring-a-players#what-accomplishments-are-you-most-proud-of\" class=\"hash-link\" aria-label=\"Direct link to What accomplishments are you most proud of?\" title=\"Direct link to What accomplishments are you most proud of?\">​</a></h4>\n<p>Ideally, candidates will tell you about accomplishments that match the job outcomes they just described to you. Even better if they match the ones of the scorecard for the position you are trying to fill.</p>\n<p>Note: <em>A players tend to talk about outcomes linked to expectations, B and C players talk generally about events, people they met, or aspects of the job they liked without ever getting into results.</em></p>\n<h4 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"what-were-some-of-the-low-points-during-that-job\">What were some of the low points during that job?<a href=\"https://didierlopes.com/blog/firing-sucks-how-to-avoid-doing-so-by-hiring-a-players#what-were-some-of-the-low-points-during-that-job\" class=\"hash-link\" aria-label=\"Direct link to What were some of the low points during that job?\" title=\"Direct link to What were some of the low points during that job?\">​</a></h4>\n<p>People can be hesitant to share their lows at first. Keep reframing the question over and over until the candidate gets the message. E.g. “<em>What went really wrong? Biggest mistake? done differently? parts you didn’t like? peers stronger than you?</em>”</p>\n<h4 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"who-were-the-people-you-worked-with\">Who were the people you worked with?<a href=\"https://didierlopes.com/blog/firing-sucks-how-to-avoid-doing-so-by-hiring-a-players#who-were-the-people-you-worked-with\" class=\"hash-link\" aria-label=\"Direct link to Who were the people you worked with?\" title=\"Direct link to Who were the people you worked with?\">​</a></h4>\n<ul>\n<li><strong>What was your boss’s name and how do you spell that?</strong></li>\n</ul>\n<p>Forcing candidates to spell the name out no matter how common it might be sends a powerful message: you are going to call, so they should tell the truth. This is referred as the “threat of reference check (TORC)”.</p>\n<ul>\n<li><strong>What was it like working with them?</strong></li>\n</ul>\n<p>Ideally, you expect high praise for their bosses and how they received mentoring and coaching from them over the years. A neutral answer will sound somewhat more reserved — not positive nor negative.</p>\n<ul>\n<li><strong>What WILL they tell me about your biggest strengths and areas to improve?</strong></li>\n</ul>\n<p>Use “will” instead of “would” so candidates know you mean business, and are therefore, more likely to tell you the truth since you will learn it from reference calls anyways. Dig in as much as you can.</p>\n<ul>\n<li><strong>How would you rate the team you inherited on an A, B, C scale? What changes did you make? Did you hire anybody? Fire anybody? How would you rate the team when you left it on A,B,C scale.</strong></li>\n</ul>\n<p>This is applicable to managers. And allows you to understand how they approach building a strong team. Do they accept the hand they have been dealt with or do they make changes to make a better hand? What changes do they make? How long does it take?</p>\n<p>Apply TORC here too: <em>“When we speak with team members of your team, what will they say were your biggest strengths and weaknesses as manager?”</em></p>\n<h4 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"why-did-you-leave-that-job\">Why did you leave that job?<a href=\"https://didierlopes.com/blog/firing-sucks-how-to-avoid-doing-so-by-hiring-a-players#why-did-you-leave-that-job\" class=\"hash-link\" aria-label=\"Direct link to Why did you leave that job?\" title=\"Direct link to Why did you leave that job?\">​</a></h4>\n<p>Was the candidate promoted, recruited or fired from each job? How did they feel about it? How did their boss react to the news? E.g. A players are highly valued by their bosses.</p>\n<p>Get curious. Find out why and stick with it until you have a clear picture of what actually happened.</p>\n<p><strong>Conducting an effective who interview</strong></p>\n<ul>\n<li>The hiring manager should conduct this interview. They own the hire, and are the ones who will suffer the consequences of making a mistake. Their career and job happiness depend on finding A players.</li>\n<li>Conduct an interview with a colleague (e.g. someone from HR, another manager or member of your team), this allows you to focus on questions and someone else to take notes.</li>\n<li>Kick off the interview by setting expectations, e.g. <em>“We are going to walk through each job you have held, for each job I am going to ask you five core questions. At the end we will discuss your career goals and aspirations and you will have a chance to ask me questions. If we mutually decide to continue, we will conduct reference calls to complete the process”.</em></li>\n</ul>\n<p><strong>Master tactics</strong></p>\n<ol>\n<li><strong>Interrupting.</strong> You have to interrupt the candidate, there is no avoiding it. At least once every 3/4 minutes. Smile broadly, match their enthusiasm level, and use reflective listening to get them to stop talking without demoralizing them.</li>\n<li><strong>The three P’s.</strong> This helps you understand how valuable an accomplishment was in any context. (1) How did the performance compare to the previous year’s performance; (2) How did your performance compare to the plan?; (3) How did your performance compare to that of peers?</li>\n<li><strong>Push versus Pull.</strong> People who perform are generally pulled to greater opportunities. People who perform poorly are often pushed out of their jobs.</li>\n<li><strong>Painting a picture.</strong> You’ll only understand what a candidate is saying when you can literally see a picture of it in your mind. Always try to put yourself in their shoes.</li>\n<li><strong>Stopping at the Stop signs.</strong> Look for shifts in body language and other inconsistencies. “We did great in that role” while shifting in their chair, looking down and covering their mouth may be a stop sign. When that happens, get curious and understand how “great” they actually did. What was actually their contribution?</li>\n</ol>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"focused-interview\">Focused Interview<a href=\"https://didierlopes.com/blog/firing-sucks-how-to-avoid-doing-so-by-hiring-a-players#focused-interview\" class=\"hash-link\" aria-label=\"Direct link to Focused Interview\" title=\"Direct link to Focused Interview\">​</a></h3>\n<p>Getting to know more. This is NOT another Who interview. It provides the chance to invite other team member to get their opinion, but the script should be followed. Think of this interview as the “odds enhancer” to truly focus on the outcomes and/or competencies on the scorecard.</p>\n<ol>\n<li>The purpose of this interview is to talk about [specific outcome or competency]</li>\n<li>What are your biggest accomplishments in this area during your career</li>\n<li>What are your insights into your biggest mistakes and lessons learned in this area?</li>\n</ol>\n<br>\n<p>Don’t be scared to use the “What? How? Tell me more” framework until you understand what the person did and how they did it.</p>\n<p>Feel free to have multiple shorter focused interviews to understand particular outcome/competencies.</p>\n<p><strong>Double-check the cultural fit.</strong> Final gauge on the cultural fit — <strong>critical!</strong> Include competencies and outcomes that go beyond the specifics of the job to embrace the larger values of your company.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"reference-interview\">Reference Interview<a href=\"https://didierlopes.com/blog/firing-sucks-how-to-avoid-doing-so-by-hiring-a-players#reference-interview\" class=\"hash-link\" aria-label=\"Direct link to Reference Interview\" title=\"Direct link to Reference Interview\">​</a></h3>\n<p>Testing what you learned. Don’t skip the references!</p>\n<ol>\n<li>Pick the right references. Review your notes from the Who interview and pick the bosses, peers, and subordinates with whom you would like to speak. Don’t just use the reference list the candidate gives you.</li>\n<li>Ask the candidate to contact the references to set up the calls. Some companies have a policy that prevents employees from serving as references, so you can increase your chances of talking with a reference if the candidate sets this up.</li>\n<li>Conduct the right number of reference interviews. The book recommends 3 past bosses, 2 peers/customers and 2 subordinates.</li>\n</ol>\n<br>\n<p><strong>Reference interview guide:</strong></p>\n<ol>\n<li><strong>In what context did you work with the person?</strong> Conversation starter and memory jogger.</li>\n<li><strong>What were the person’s biggest strengths?</strong> Ask for multiple examples to put strengths and development areas into context. Don’t forget to get curious by using “What? How? Tell me more” framework to clarify responses.</li>\n<li><strong>What were the person’s biggest areas for improvement back then?</strong> The wording ‘back then’ liberates the reference to talk about weaknesses that existed in the past. “In truth, we believe, people don’t change that much. People aren’t mutual funds. Past performance really is an indicator of future performance.”</li>\n<li><strong>How would you rate their overall performance in that job on a 1–10 scale?</strong> What about their performance causes you to give that rating? Remember that 6 is really a 2. How does this rating compare with what the candidate said in advance? Wide discrepancy is alarming.</li>\n<li><strong>The person mentioned that they struggled with ____ on that job. Can you talk more about that?</strong> Test something the candidate told you by framing it as a question for the reference. E.g. “the person mentioned that you MIGHT SAY he was disorganized. Can you tell me more about that?” the wording is again very important as ‘might say’ suggests to the reference that they have permission to talk about the subject because the candidate raised it.</li>\n</ol>\n<br>\n<p>These questions follow the same pattern as the other interviews. This makes it very easy to merge what you hear with what you have already learned about a candidate.</p>\n<p><strong>Tips:</strong></p>\n<ul>\n<li><strong>Avoid accepting a candidate’s reference list at face value.</strong> E.g. either use your own network for gathering objective unbiased data or try to reach out to subordinates or people two levels below who interacted with the candidate to get a more honest answer.</li>\n<li><strong>Hearing or understanding the code for risky candidates.</strong> Be able to read between lines. People don’t like to give negative reference, so your best defense is to pay close attention to what people say and how they say it. Examples of bad signs: If they just confirm dates of employment, um’s and er’s is hesitation, absence of enthusiasm (faint praise).</li>\n</ul>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"decide-who-to-hire\">Decide who to hire<a href=\"https://didierlopes.com/blog/firing-sucks-how-to-avoid-doing-so-by-hiring-a-players#decide-who-to-hire\" class=\"hash-link\" aria-label=\"Direct link to Decide who to hire\" title=\"Direct link to Decide who to hire\">​</a></h3>\n<p><strong>Skill-Will Bull’s Eye</strong></p>\n<p>Does somebody’s skill (what they can do) and will (what they want to do) match your scorecard? This is a person’s skill-will profile.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2023-01-02-firing-sucks-how-to-avoid-doing-so-by-hiring-a-players_3-c37bb57c0d6c5752f8f3edd81f73f535.webp\" width=\"1400\" height=\"574\" class=\"img_ev3q\"></p>\n<p>You should have plenty of data at this stage to make this assessment.</p>\n<ul>\n<li><strong>Skill has to do with a candidate’s ability to achieve the individual outcomes on your scorecard.</strong> If you believe a candidate has a 90% or better chance to achieve a certain outcome based on the data gathered, rate them an A, otherwise a B or a C. Repeat for each outcome.</li>\n<li><strong>Will has to do with the motivations and competencies a candidate brings to the table.</strong> For each competency, does the data suggest there is a 90% or better chance that the candidate will display that competency? If so rate them an A, otherwise a B or C. Repeat for each competency.</li>\n</ul>\n<p>An A player is someone whose skill and will match your scorecard. Anything less is a B or C, no matter the experience or seeming talent level.</p>\n<p><strong>Red Flags: When to dive beneath the surface</strong></p>\n<p>These flags may not be deal killers, but they are likely to signal that there is something worth exploring beneath the surface:</p>\n<ul>\n<li>Does not mention past failures</li>\n<li>Exaggerates their answers</li>\n<li>Takes credit for the work of others</li>\n<li>Speaks poorly of past bosses</li>\n<li>Cannot explain job moves</li>\n<li>People most important to the candidate are unsupportive of a change</li>\n<li>For managerial hires, never had to hire or fire anybody</li>\n<li>Seems more interested in compensation and benefits than in the job itself</li>\n<li>Tries too hard to look like an expert</li>\n<li>Self-absorbed</li>\n</ul>\n<p>More behavioral warning signs:</p>\n<ul>\n<li>Winning too much</li>\n<li>Adding too much value</li>\n<li>Starting a sentence with ‘no’, ‘but’, or ‘however’</li>\n<li>Telling the world how smart we are</li>\n<li>Making destructive comments about previous colleagues</li>\n<li>Blaming others</li>\n<li>Making excuses</li>\n<li>The excessive need to ‘be me’</li>\n</ul>\n<p><strong>How to decide:</strong></p>\n<ol>\n<li>Take out your scorecards that you have completed on each candidate</li>\n<li>Make sure you have rated all of the candidates on the scorecard. If you have not given each candidate an overall A, B or C grade, do so now. Make any updates you need to based on the reference interviews. Look at the data, consider the opinions and observations of the interview team, and give a final grade.</li>\n<li>If you have no A’s, then restart your process and the second step: source.</li>\n<li>If you have one A, decide to hire that person.</li>\n<li>If you have multiple A’s, then rank them and decide to hire the best A among them.</li>\n</ol>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"sell\">Sell<a href=\"https://didierlopes.com/blog/firing-sucks-how-to-avoid-doing-so-by-hiring-a-players#sell\" class=\"hash-link\" aria-label=\"Direct link to Sell\" title=\"Direct link to Sell\">​</a></h2>\n<p>Once candidates pass the selection, persuade them to join. The key to successfully selling your candidate to your company is putting yourself in their shoes.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"five-fs-of-selling\">Five F’s of selling<a href=\"https://didierlopes.com/blog/firing-sucks-how-to-avoid-doing-so-by-hiring-a-players#five-fs-of-selling\" class=\"hash-link\" aria-label=\"Direct link to Five F’s of selling\" title=\"Direct link to Five F’s of selling\">​</a></h3>\n<p>There are 5 areas that candidates tend to care about, make sure to address each of these 5 areas until you get the person onboard.</p>\n<ol>\n<li><strong>Selling Fit:</strong> This ties together the company’s vision, needs and culture with the candidate’s goals, strengths and values.</li>\n<li><strong>Selling Family:</strong> Takes into account the broader trauma of changing jobs.</li>\n<li><strong>Selling Freedom:</strong> The autonomy the candidate will have to make their own decisions.</li>\n<li><strong>Selling Fortune:</strong> Reflects the stability of your company and the overall financial upside.</li>\n<li><strong>Selling Fun:</strong> Describes the work environment and personal relationships the candidate will make.</li>\n</ol>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"five-waves-of-selling\">Five waves of selling<a href=\"https://didierlopes.com/blog/firing-sucks-how-to-avoid-doing-so-by-hiring-a-players#five-waves-of-selling\" class=\"hash-link\" aria-label=\"Direct link to Five waves of selling\" title=\"Direct link to Five waves of selling\">​</a></h3>\n<p>Selling should be something that happens throughout the entire hiring process. In particular, there are five distinct phases that merit increased selling effort:</p>\n<ol>\n<li>When you source</li>\n<li>When you interview</li>\n<li>The time between your offer and the candidate acceptance</li>\n<li>The time between the candidate’s acceptance and their first day</li>\n<li>The new hire’s first one hundred days on the job</li>\n</ol>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"persistent-pays-off\">Persistent pays off<a href=\"https://didierlopes.com/blog/firing-sucks-how-to-avoid-doing-so-by-hiring-a-players#persistent-pays-off\" class=\"hash-link\" aria-label=\"Direct link to Persistent pays off\" title=\"Direct link to Persistent pays off\">​</a></h3>\n<p>Once you have identified the right candidate, you must be persistent and do whatever you can to sign the deal.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"how-to-sell-a-players\">How to: sell A Players<a href=\"https://didierlopes.com/blog/firing-sucks-how-to-avoid-doing-so-by-hiring-a-players#how-to-sell-a-players\" class=\"hash-link\" aria-label=\"Direct link to How to: sell A Players\" title=\"Direct link to How to: sell A Players\">​</a></h3>\n<ol>\n<li>Identify which of the five F’s really matter to the candidate.</li>\n<li>Create and execute a plan to address the relevant F’s during the five waves of selling.</li>\n<li>Be persistent. Don’t give up until you have your A player on board.</li>\n</ol>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"conclusion\">Conclusion<a href=\"https://didierlopes.com/blog/firing-sucks-how-to-avoid-doing-so-by-hiring-a-players#conclusion\" class=\"hash-link\" aria-label=\"Direct link to Conclusion\" title=\"Direct link to Conclusion\">​</a></h2>\n<p>In a more simplistic image, this is what the A method boils down too.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2023-01-02-firing-sucks-how-to-avoid-doing-so-by-hiring-a-players_4-3a1fc133dbf2754e04bf9a42712dc5f3.webp\" width=\"978\" height=\"818\" class=\"img_ev3q\"></p>\n<p>I really enjoyed reading this book and I am taking a lot of these learnings to improve the hiring processes at OpenBB.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/firing-sucks-how-to-avoid-doing-so-by-hiring-a-players",
            "title": "Firing sucks. How to avoid doing so by hiring A players.",
            "summary": "Firing is tough. This blogpost discusses how to avoid it by hiring A players, improving the hiring process, and understanding the importance of a scorecard in recruitment.",
            "date_modified": "2023-01-02T00:00:00.000Z",
            "tags": [
                "hiring",
                "management",
                "a-players",
                "openbb",
                "career-advice"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/how-chatgpt-allowed-me-to-leverage-twitter-api-10x-faster",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2022-12-11-how-chatgpt-allowed-me-to-leverage-twitter-api-10x-faster.webp\"></p>\n<br>\n<p>Leveraging the power of ChatGPT to interact with Twitter API for real-time financial news updates.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>For a while now, users have been asking for adding real-time financial news on <a href=\"https://github.com/OpenBB-finance/OpenBBTerminal\" target=\"_blank\" rel=\"noopener noreferrer\">OpenBB Terminal</a>.</p>\n<p>Since OpenBB Terminal is a command line interface for the world’s financial data, and there is no threading going on — there was never a very straightforward way to do this.</p>\n<p><strong>Until today.</strong></p>\n<p>After recalling <a href=\"https://twitter.com/elonmusk/status/1591121142961799168?s=20&amp;t=j-cjTu-XA9SNcY8PBrbUnQ\" target=\"_blank\" rel=\"noopener noreferrer\">this tweet</a> from Elon earlier in November, I realized that I’ve been using Twitter for news substantially more than MSM.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2022-12-11-how-chatgpt-allowed-me-to-leverage-twitter-api-10x-faster_1-32b14b12aa466fe678486fbb430b9255.webp\" width=\"1186\" height=\"764\" class=\"img_ev3q\"></p>\n<p>So, my next train of thought was; What if I was able to somehow display the latest tweets from Twitter accounts that I trust. In particular, accounts that have up-to-date information and usually mention the words “JUST IN” or “BREAKING”. E.g. <a href=\"https://twitter.com/WatcherGuru\" target=\"_blank\" rel=\"noopener noreferrer\">@WatcherGuru</a> or <a href=\"https://twitter.com/unusual_whales\" target=\"_blank\" rel=\"noopener noreferrer\">@unusual_whales</a>.</p>\n<p>By doing this, I could then use the bottom of the OpenBB Terminal to highlight the news. An example of this is below:</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2022-12-11-how-chatgpt-allowed-me-to-leverage-twitter-api-10x-faster_2-7a45f1f461063a515e7a46db1616e448.webp\" width=\"1400\" height=\"579\" class=\"img_ev3q\"></p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"coding-and-chatgpt\">Coding and ChatGPT<a href=\"https://didierlopes.com/blog/how-chatgpt-allowed-me-to-leverage-twitter-api-10x-faster#coding-and-chatgpt\" class=\"hash-link\" aria-label=\"Direct link to Coding and ChatGPT\" title=\"Direct link to Coding and ChatGPT\">​</a></h2>\n<p>The next step for me was to implement the code!</p>\n<p>First, I needed to understand how I could have access to the last tweet of a specific user account. I already had a Twitter API account created, which meant I already had the key, token and secrets, therefore, I just needed to read documentation to understand how to use the Twitter API. Hence, I started reading <a href=\"https://developer.twitter.com/en/docs/twitter-api/tweets/search/api-reference/get-tweets-search-recent\" target=\"_blank\" rel=\"noopener noreferrer\">Twitter’s developer documentation</a>.</p>\n<p>The day before I had been playing around with ChatGPT. And like everyone else, I was very impressed. One of the things that surprised me the most was how good it was at outputting working code with an explanation along the lines.</p>\n<p>So, while I was reading the documentation, I was thinking “I wish there was a way for me to just be able to get the last N tweets of an account without needing to dig in the developer documentation”. Could ChatGPT be the answer?</p>\n<p>So I tried…</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2022-12-11-how-chatgpt-allowed-me-to-leverage-twitter-api-10x-faster_3-f535ae3b9673cbcc33f014cf30b0bbc2.webp\" width=\"1262\" height=\"1896\" class=\"img_ev3q\"></p>\n<p>This was already amazing. But I’m lazy and didn’t want to copy all the cells individually to put it into a Jupyter notebook, so asked ChatGPT to provide the code output as a single block. I wasn’t convinced it was going to work. <strong>But it did</strong>.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2022-12-11-how-chatgpt-allowed-me-to-leverage-twitter-api-10x-faster_4-85847d27be1ad71b03d214e161e4d3c9.webp\" width=\"1256\" height=\"1502\" class=\"img_ev3q\"></p>\n<p>… it just worked. 🤯</p>\n<p>After that, I needed the timestamp associated with the tweet, to see how old it was. As usual, I started looking into <a href=\"https://docs.tweepy.org/en/latest/authentication.html#twitter-api-v2\" target=\"_blank\" rel=\"noopener noreferrer\">Tweepy documentation</a>.</p>\n<p><strong>Ups, what was I doing again?</strong></p>\n<p>After a couple of seconds, I went onto ChatGPT and asked how I could get the timestamp of a tweet using Tweepy library.</p>\n<p><strong>And 🪄, it worked again!!!</strong></p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2022-12-11-how-chatgpt-allowed-me-to-leverage-twitter-api-10x-faster_5-4a3ab5dadca3e7dde237b412f7bda43e.webp\" width=\"1266\" height=\"1696\" class=\"img_ev3q\"></p>\n<p>One thing that is for sure: ChatGPT is going to truly disrupt many industries. And I will be here for it.</p>\n<p>PS: The PR with this addition is in development <a href=\"https://github.com/OpenBB-finance/OpenBBTerminal/pull/3757\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/how-chatgpt-allowed-me-to-leverage-twitter-api-10x-faster",
            "title": "How ChatGPT allowed me to leverage Twitter API 10x faster",
            "summary": "Leveraging the power of ChatGPT to interact with Twitter API for real-time financial news updates.",
            "date_modified": "2022-12-11T00:00:00.000Z",
            "tags": [
                "chatgpt",
                "twitter-api",
                "tweepy",
                "python",
                "programming"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/how-i-wrote-a-machine-learning-paper-in-1-week-that-got-accepted-to-icmla",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2022-12-07-how-i-wrote-a-machine-learning-paper-in-1-week-that-got-accepted-to-icmla.webp\"></p>\n<br>\n<p>How I wrote a machine learning paper in 1 week that got accepted to ICMLA while working full time and raised $8.8 million for OpenBB Terminal.</p>\n<p>The open source code is available <a href=\"https://github.com/DidierRLopes/step-detection-ML\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>One year ago, I raised $ 8.8 millions to build <a href=\"https://github.com/OpenBB-finance/OpenBBTerminal\" target=\"_blank\" rel=\"noopener noreferrer\">OpenBB Terminal</a> full time. But since I was working at a startup in the UK, I had a 3 month notice period.</p>\n<p>During that time I worked on documenting pretty much everything I had been working on, BUT that felt short. I felt like the data that came out of our <a href=\"http://www.nurvv.com/\" target=\"_blank\" rel=\"noopener noreferrer\">NURVV Run</a> product could be used with a machine learning algorithm in order to detect a foot strike quite efficiently.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2022-12-07-how-i-wrote-a-machine-learning-paper-in-1-week-that-got-accepted-to-icmla_1-9cd87b7464df9801e2bcf027d82779e2.webp\" width=\"1316\" height=\"438\" class=\"img_ev3q\"></p>\n<p>So I asked my company:</p>\n<blockquote>\n<p><em>If I use my spare time to work on this paper will you sponsor me if I get accepted?</em></p>\n</blockquote>\n<br>\n<p><strong>My goal was to increase the visibility of our product in academia.</strong> And given I spent some time reading papers in the area, I knew that what I had in mind had a shot at working.</p>\n<p><strong>My background is not data science, and this was my first time “officially” working on machine learning.</strong> I wasn’t 100% sure that my idea would work, but after spending more than 1 year at the company, I knew how the data behaved. I thought I could build an algorithm robust enough to be able to detect a foot strike more efficiently than what others had.</p>\n<p>After some time, the company accepted my proposal, and between the time to decide to apply to <a href=\"https://www.icmla-conference.org/icmla21/\" target=\"_blank\" rel=\"noopener noreferrer\">International Conference on Machine Learning and Applications (ICMLA)</a> and getting ready to start working on the paper, there was 1 week left.</p>\n<p>I thought that this window was rather tight given that I had to clean the data, work on the entire code behind the paper from idea to implementation, and write the damn paper. <strong>I knew this was gonna be tight, but oh boy.</strong> I had one of the harshest weeks of my life. I barely slept for 7 straight days, and skipped the company team event in order to make it through the deadline.</p>\n<p>Because of that, I will go into what happened at each step along the way with images. I will skip the cleaning data and boring parts, don’t worry. If you just want to read the final paper, you can find it here: <a href=\"https://ieeexplore.ieee.org/abstract/document/9680024\" target=\"_blank\" rel=\"noopener noreferrer\">”Step Detection using SVM on NURVV Trackers”</a>.</p>\n<p>Also, if you’ve been following me, you know how much I love open source. Owing to that I open source the code behind the project <a href=\"https://github.com/DidierRLopes/step-detection-ML\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"exploratory-data-analysis\">Exploratory Data Analysis<a href=\"https://didierlopes.com/blog/how-i-wrote-a-machine-learning-paper-in-1-week-that-got-accepted-to-icmla#exploratory-data-analysis\" class=\"hash-link\" aria-label=\"Direct link to Exploratory Data Analysis\" title=\"Direct link to Exploratory Data Analysis\">​</a></h2>\n<p>The Nurvv trackers have an <strong>Inertial Measurement Unit (IMU) tracks linear acceleration (accelerometer) and rotational rate (gyroscope)</strong>. Sometimes it also contains a magnetometer. And Nurvv gave me access to 6 runs from 6 different runners.</p>\n<p>My first step was to look into how this data looked. On the left you can see the acceleration (m/s²) and the angular velocity (rad/s).</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2022-12-07-how-i-wrote-a-machine-learning-paper-in-1-week-that-got-accepted-to-icmla_2-7e034fc7138a45efa5223096dfa3d03e.webp\" width=\"850\" height=\"676\" class=\"img_ev3q\"></p>\n<p>I knew that our <strong>IMU had a sampling rate of 1125 Hz</strong> (which means that each data point gets sampled at approximately every 888.89μs) and <strong>this was critical in order to detect the oscillations that occur when a foot strike occurs</strong> (i.e. impact of the foot on the floor makes the IMU oscillate). Thus I zoomed in the zone of impact and used a scatter plot to understand if we were “missing” information.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2022-12-07-how-i-wrote-a-machine-learning-paper-in-1-week-that-got-accepted-to-icmla_3-9f6f835eac9c3653e04e86d914c90a49.webp\" width=\"1282\" height=\"406\" class=\"img_ev3q\"></p>\n<p>I found it interesting that <strong>the distance between the samples were larger at the time of the impact</strong>. So I plotted the IMU accelerometer data and the IMU gyroscope data in a 3D plot interactively as a function of time (below you can see a snapshot).</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2022-12-07-how-i-wrote-a-machine-learning-paper-in-1-week-that-got-accepted-to-icmla_4-494f608dc3f58c62289ba8f697b800f0.webp\" width=\"1244\" height=\"586\" class=\"img_ev3q\"></p>\n<p>From here it was interesting to note that when the foot is in the air, the samples are somehow concentrated (darker blue), whereas when a step occurs (more sparse) they behave erratically. The plot above was snapshotted with 3 steps that occurred.</p>\n<p>From that 3D plot I had the intuition that by utilizing a <strong>principal component analysis (PCA</strong>)**, I could reduce the dimensionality without losing much information. The result is shown below,</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2022-12-07-how-i-wrote-a-machine-learning-paper-in-1-week-that-got-accepted-to-icmla_5-6e477a1448cda0b28c002e82cf6e68fc.webp\" width=\"1288\" height=\"540\" class=\"img_ev3q\"></p>\n<p>This made me think that I could use a <strong>support vector machine (SVM)</strong> in order to detect whether a foot strike has occurred or not. And what I was most excited about it was:</p>\n<ul>\n<li><strong>This model isn’t time-dependant.</strong> Meaning that it would be fascinating to be able to predict whether a step occurred or not without the notion of time, but the current IMU data.</li>\n<li>We can develop an SVM model for each runner style. Then create an <strong>ensemble model with hard voting</strong> which allowed for the model that has seen more similar data, to be more confident in the classification of foot strike vs not foot strike.</li>\n</ul>\n<p>But this was all a theory, I needed to prove it.</p>\n<p>The first issue I had was: <strong>SVM is a supervised learning model</strong>. This meant that for the sampling data I was providing the model, I would have to classify whether those samples corresponded to a foot strike or not.</p>\n<p><strong>The issue?</strong> Although the product had <strong>force sensitive resistors (FSR)</strong> in the insoles, I didn’t have access to the samples that corresponded with these IMU samples.</p>\n<p>So I knew that I would have to classify the data myself. Manually would have been a nightmare and not reliable enough, so I needed to build an algorithm that could classify the data quite reliably. <strong>Signal processing theory, here I go.</strong></p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"labelling-data-for-a-supervised-learning-problem\">Labelling data for a supervised learning problem<a href=\"https://didierlopes.com/blog/how-i-wrote-a-machine-learning-paper-in-1-week-that-got-accepted-to-icmla#labelling-data-for-a-supervised-learning-problem\" class=\"hash-link\" aria-label=\"Direct link to Labelling data for a supervised learning problem\" title=\"Direct link to Labelling data for a supervised learning problem\">​</a></h3>\n<ol>\n<li>Get the raw IMU samples (accelerometer and gyroscope)</li>\n<li>Do the difference in magnitude between the accelerometers samples and then the gyroscope samples</li>\n<li>Apply root sum squared to the magnitude difference of accelerometer data, and then similarly to gyroscope data</li>\n<li>Standardize the accelerometer data and the gyroscope data. This is so the data can be somehow compared with each other since the magnitude varies as one represents linear acceleration and the other angular rate.</li>\n<li>Do the average between these 2 signals. This makes the data more robust.</li>\n<li>Finally, apply a convolution to the resulting signal with a rectangular pulse. This allows to remove “drops” from the signal and ensures a smoother signal.</li>\n</ol>\n<br>\n<p>Below you can see the formulas and signal changes that were made in order to obtain the final result:</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2022-12-07-how-i-wrote-a-machine-learning-paper-in-1-week-that-got-accepted-to-icmla_6-dff360f2f8fe05416dc547e784ebd336.webp\" width=\"1400\" height=\"541\" class=\"img_ev3q\"></p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2022-12-07-how-i-wrote-a-machine-learning-paper-in-1-week-that-got-accepted-to-icmla_7-953faecf2ccc6015f4c57efaa2bab860.webp\" width=\"1400\" height=\"513\" class=\"img_ev3q\"></p>\n<p>After this, I selected a sensible value of 0.3 to be used as a threshold on the resulting signal to classify step vs no-step.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2022-12-07-how-i-wrote-a-machine-learning-paper-in-1-week-that-got-accepted-to-icmla_8-3d4ffe542f5543407d621cf9737a0fdd.webp\" width=\"1396\" height=\"792\" class=\"img_ev3q\"></p>\n<p>I applied the difference between each first foot strike detected in order to make sure that there was no missed step. As you can see above the stride time is around 700ms which is what is expected of a runner jogging.</p>\n<p>Someone might be wondering; If this gives such a great result, why did I need machine learning in the first place? <strong>The reason is because standardization and convolution (steps 4 and steps 6) are a post-processing signal technique.</strong> Therefore, it cannot be deployed in running time, and relies on data that happens in the future.</p>\n<p>For illustration purposes, here is how the initial raw IMU data behaves against the labelling from signal processing approach (red background means no step, while green background means step).</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2022-12-07-how-i-wrote-a-machine-learning-paper-in-1-week-that-got-accepted-to-icmla_9-c76d9d3cca537f2853867e5eb4f310f6.webp\" width=\"1376\" height=\"1098\" class=\"img_ev3q\"></p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"support-vector-machine-for-classification\">Support Vector Machine for classification<a href=\"https://didierlopes.com/blog/how-i-wrote-a-machine-learning-paper-in-1-week-that-got-accepted-to-icmla#support-vector-machine-for-classification\" class=\"hash-link\" aria-label=\"Direct link to Support Vector Machine for classification\" title=\"Direct link to Support Vector Machine for classification\">​</a></h2>\n<p>For the model, SVM was selected because:</p>\n<ul>\n<li>It works well with high dimensional data (6 IMU samples) because it only uses a few of these points (called support vectors) to create this hyperplane (decision boundary) between classes.</li>\n<li>SVM is ideal for binary classification problems.</li>\n<li>RBF kernel allows to handle non-linear data.</li>\n</ul>\n<p>This is the type of classification that SVM is capable of (this is the raw acceleration data with a PCA applied, and the SVM classification on the background for a model that was trained using that same data).</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2022-12-07-how-i-wrote-a-machine-learning-paper-in-1-week-that-got-accepted-to-icmla_10-b254e91415b252be259cda37e4ce3738.webp\" width=\"1400\" height=\"1031\" class=\"img_ev3q\"></p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"c-and-gamma-hyperparameters\">C and gamma hyperparameters<a href=\"https://didierlopes.com/blog/how-i-wrote-a-machine-learning-paper-in-1-week-that-got-accepted-to-icmla#c-and-gamma-hyperparameters\" class=\"hash-link\" aria-label=\"Direct link to C and gamma hyperparameters\" title=\"Direct link to C and gamma hyperparameters\">​</a></h3>\n<ul>\n<li>Given each dataset is rather large to perform <strong>grid search optimization</strong> on C and gamma, a subset of each of the datasets is used to extract these parameters.</li>\n<li>Each dataset subset is now split: 80% for training data and 20% for validation.</li>\n<li>Thus, 80% of the data subset is used to apply SVM with different combinations of C and gamma over a 2D grid. The remaining 20% is used to test the logistic loss and assess optimal hyperparameters.</li>\n</ul>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"training-and-testing\">Training and testing<a href=\"https://didierlopes.com/blog/how-i-wrote-a-machine-learning-paper-in-1-week-that-got-accepted-to-icmla#training-and-testing\" class=\"hash-link\" aria-label=\"Direct link to Training and testing\" title=\"Direct link to Training and testing\">​</a></h3>\n<ul>\n<li>80% of data is used for training and 20% is used for testing.</li>\n<li>Although the testing is done <strong>out-of-sample</strong>, given the nature of the data (where it comes from the same distribution) it is almost as if it was an <strong>in-sample</strong>.</li>\n<li>In our case this is ideal as we want each model to perform very well on its own dataset. We want each model to generalize well for that very specific type of data (runner style, speed and terrain).</li>\n<li>A 5-sample moving average is applied before assessing the classification of our model, this is to remove spurious samples. A small window needs to be selected to not introduce a delay in the recognition of a step.</li>\n<li>Since our data set is imbalanced (i.e. there are more samples being no-step than step samples) we’ll use <strong>Geometric Mean (G-Mean) evaluation score</strong>, since this measure tries to maximize the accuracy on each of the classes while keeping their accuracies balanced.</li>\n</ul>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"result\">Result<a href=\"https://didierlopes.com/blog/how-i-wrote-a-machine-learning-paper-in-1-week-that-got-accepted-to-icmla#result\" class=\"hash-link\" aria-label=\"Direct link to Result\" title=\"Direct link to Result\">​</a></h3>\n<p>In the same dataset where we trained our SVM, we were able to achieve a G-Mean of 0.9645. This is rather expected since this is a powerful model and it was trained on that same data.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2022-12-07-how-i-wrote-a-machine-learning-paper-in-1-week-that-got-accepted-to-icmla_11-185986a6c08b6879102fcb90948e57c5.webp\" width=\"1386\" height=\"520\" class=\"img_ev3q\"></p>\n<p>From the graph above this result is very positive given that the mislabelling always occurs at the boundary of a step / no-step detection. And since the sampling occurs very fast, we have some margin of error.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"ensemble-svm-model-architecture\">Ensemble SVM model architecture<a href=\"https://didierlopes.com/blog/how-i-wrote-a-machine-learning-paper-in-1-week-that-got-accepted-to-icmla#ensemble-svm-model-architecture\" class=\"hash-link\" aria-label=\"Direct link to Ensemble SVM model architecture\" title=\"Direct link to Ensemble SVM model architecture\">​</a></h2>\n<p>This model as expected had a poor performance in an unseen dataset. This is normal as the data came from a different runner, running at a different speed in a different terrain. Thus, in order to create a more robust model, we built this ensemble SVM model architecture.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2022-12-07-how-i-wrote-a-machine-learning-paper-in-1-week-that-got-accepted-to-icmla_12-16510a285b00e08098b2bb6b6ba113cc.webp\" width=\"1372\" height=\"750\" class=\"img_ev3q\"></p>\n<p>Each dataset has the signal processing technique applied in order to obtain the labelling. With this labels, an SVM model can be trained.</p>\n<p>Then, an <strong>unseen dataset</strong> (not used for training) will be used as input for all the trained SVM models. I.e. each input (3 accelerometer samples and 3 gyroscope samples) will be given to each SVM model which will output 0 or 1 to denote no-step or step, respectively.</p>\n<p>My rationale there was: <em>I could do a major voting approach, BUT because of how I trained the data. It could happen that one of the models had the sample being very inside the boundary, whereas 2 others had it just outside, and the later would win. This is not what I was looking for.</em></p>\n<p>Because of this boundary approach associated with SVMs, I knew that although SVM doesn’t provide probability estimates directly, these could be calculated. So I took advantage of that. And used that probability estimate to select whether the input was considered a stop or not. My rationale was: the model that has seen more similar IMU samples is likely to have a higher confidence in their output and as output they will have what I provided as a label in advance.</p>\n<p>Finally, I applied a <strong>5-sample moving average</strong> to the step (1) / no-step (0) output and round the value to be classified as step and no-step. This allowed to remove spurious samples.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"results\">Results<a href=\"https://didierlopes.com/blog/how-i-wrote-a-machine-learning-paper-in-1-week-that-got-accepted-to-icmla#results\" class=\"hash-link\" aria-label=\"Direct link to Results\" title=\"Direct link to Results\">​</a></h3>\n<p>The prediction for a single SVM was extremely accurate because the model was trained on data samples from that same run (i.e. distribution). On the other hand, the ensemble prediction didn’t run on data from that distribution, hence, making this problem much more complex. However, even with that constraint, a G-Mean of 0.8756 was still achieved.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2022-12-07-how-i-wrote-a-machine-learning-paper-in-1-week-that-got-accepted-to-icmla_13-d585519cd68350934b4ce2454158503b.webp\" width=\"1256\" height=\"388\" class=\"img_ev3q\"></p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"future-work\">Future work<a href=\"https://didierlopes.com/blog/how-i-wrote-a-machine-learning-paper-in-1-week-that-got-accepted-to-icmla#future-work\" class=\"hash-link\" aria-label=\"Direct link to Future work\" title=\"Direct link to Future work\">​</a></h2>\n<ul>\n<li>Employ the data coming from the ”smart” insoles as an alternative ground-truth for determining step versus no-step conditions.</li>\n<li>The diversity of the data set can also be expanded to account for more surfaces, running speeds and styles.</li>\n<li>Explore whether the characteristics of the PCA plot of IMU data can be used to categorize different running styles.</li>\n<li>The exploration of different classification algorithms for the step detection problem, e.g. applying a long-short term memory (LTSM) neural network algorithm to exploit the time-dependency between samples.</li>\n<li>Implement this proof-of-concept code on the production NURVV Run system, to test the prediction technique in a real-life scenario and consider computational time.</li>\n</ul>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"final-remarks\">Final remarks<a href=\"https://didierlopes.com/blog/how-i-wrote-a-machine-learning-paper-in-1-week-that-got-accepted-to-icmla#final-remarks\" class=\"hash-link\" aria-label=\"Direct link to Final remarks\" title=\"Direct link to Final remarks\">​</a></h2>\n<p>This was my first most technical blogpost where I went into details in how I wrote a ML paper that was accepted in a major conference in 1 week. Would love to know your thoughts on it.</p>\n<p>Feel free to check the full paper version here: <a href=\"https://ieeexplore.ieee.org/abstract/document/9680024\" target=\"_blank\" rel=\"noopener noreferrer\">https://ieeexplore.ieee.org/abstract/document/9680024</a></p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/how-i-wrote-a-machine-learning-paper-in-1-week-that-got-accepted-to-icmla",
            "title": "How I wrote a machine learning paper in 1 week that got accepted to International Conference in Machine Learning Applications",
            "summary": "How I wrote a machine learning paper in 1 week that got accepted to ICMLA while working full time and raised $8.8 million for OpenBB Terminal.",
            "date_modified": "2022-12-07T00:00:00.000Z",
            "tags": [
                "machine-learning",
                "data-science",
                "academia",
                "icmla",
                "nurvv-run",
                "open-source"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/the-future-of-finance-with-open-source-and-ai",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2022-12-04-the-future-of-finance-with-open-source-and-ai.webp\"></p>\n<br>\n<p>The future of finance is being reshaped by open source and AI. This post discusses the potential of these technologies in disrupting the financial industry, the advantages of open source, and the role of AI in user interface.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>This post will talk about my (very) u̶n̶biased opinion about the future of finance built on top of open source and AI.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"open-source-platform\">Open Source platform<a href=\"https://didierlopes.com/blog/the-future-of-finance-with-open-source-and-ai#open-source-platform\" class=\"hash-link\" aria-label=\"Direct link to Open Source platform\" title=\"Direct link to Open Source platform\">​</a></h2>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2022-12-04-the-future-of-finance-with-open-source-and-ai_1-06d02a8de61cf5c3a9bc1a237d229060.webp\" width=\"1218\" height=\"917\" class=\"img_ev3q\"></p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"data-licensing-vs-marketplace\">Data licensing vs Marketplace<a href=\"https://didierlopes.com/blog/the-future-of-finance-with-open-source-and-ai#data-licensing-vs-marketplace\" class=\"hash-link\" aria-label=\"Direct link to Data licensing vs Marketplace\" title=\"Direct link to Data licensing vs Marketplace\">​</a></h3>\n<p>Current monopolies spend an enormous amount of cash on financial data licensing. There are dozens of different asset classes (stocks, options, crypto, NFTs, currencies, bonds, ETFs, mutual funds, …) and these often vary based on geography. <strong>That makes the overall investment research industry a very tough market to compete.</strong> Startups cannot disrupt the space without a massive capital injection. This is also why startups usually focus on a certain asset class in a certain geography.</p>\n<p><strong>In my opinion, the only shot we have to disrupt incumbents is by not owning the data but becoming the infra layer between data sources and users.</strong> <em>This is no different than Uber not owning cars, Airbnb not owning apartments or Deliveroo not owning restaurants.</em></p>\n<p><strong>This also has a great advantage which is being able to integrate new data sources very fast and easily.</strong> Plus, owing to open source, anyone can add it. On the other hand, it’s very unlikely that an incumbent will add data that you require. Plus, if they do, they will need to license the data and therefore decrease their margins — unless they increase the price to users.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"full-price-bundle\">Full-price bundle<a href=\"https://didierlopes.com/blog/the-future-of-finance-with-open-source-and-ai#full-price-bundle\" class=\"hash-link\" aria-label=\"Direct link to Full-price bundle\" title=\"Direct link to Full-price bundle\">​</a></h3>\n<p>Current incumbents pricing is usually a complete bundled offering. <strong>This means that regardless of what you are utilizing in terms of both breadth and depth, you pay the full price tag.</strong> A good analogy is like a restaurant ONLY having a buffet when all you want is a bottle of water, or some chips. What happens is that a user ends up paying for data that they are not using.</p>\n<p>In 2022, this is a very outdated take. Companies are looking to get leaner, and it doesn’t make sense to pay for data that you aren’t going to leverage. <strong>Being the infrastructure between users and data sources allows you to create value to both</strong>; Since users will have access to all the data they want and pay for the ones they use, and data sources will have access to a big pool of users and may not need to create a dashboard product to monetize their offerings.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"transparency--customization\">Transparency &amp; Customization<a href=\"https://didierlopes.com/blog/the-future-of-finance-with-open-source-and-ai#transparency--customization\" class=\"hash-link\" aria-label=\"Direct link to Transparency &amp; Customization\" title=\"Direct link to Transparency &amp; Customization\">​</a></h3>\n<p>Current incumbents have built several in-house financial models. <strong>Although these are often customizable, their customization is typically limited.</strong> That is because what is usually customizable are the values/weights, but not necessarily the formulas — that is kept hidden in their source code. This is an issue because that code cannot be validated and users cannot modify it.</p>\n<p>With open source, the story is completely different. <strong>Users can see every single line of code, and therefore not only audit the code quality but adapt the models/formulas to their own needs.</strong> At the end of the day, there is no point in re-inventing the wheel for financial theory that has been around for decades.</p>\n<p>By having the code open source, users can rely on the fact that these formulas have been validated/tested by thousands or millions of users and, therefore, there’s a very low chance that these are wrong. <strong>In addition, users are more secure because they can investigate the code and check/fix any vulnerabilities.</strong></p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"community\">Community<a href=\"https://didierlopes.com/blog/the-future-of-finance-with-open-source-and-ai#community\" class=\"hash-link\" aria-label=\"Direct link to Community\" title=\"Direct link to Community\">​</a></h3>\n<p>One of the best parts of open source is the integrated community that it creates. This attracts people from every background, gender or ethnicity. Such a pool of diversity tends to allow for better ideas and pushes a project further. With people from the community being able to contribute, this also drives innovation.</p>\n<p><a href=\"http://my.openbb.co/app/terminal/community-routines\" target=\"_blank\" rel=\"noopener noreferrer\">OpenBB</a> has been driven a lot by the community so far. What started as a terminal mostly focused on stocks, soon evolved into including a broad range of datasets and considering several geographies. E.g. A contributor from Sweeden integrated Avanza API to the mutual funds menu that would only appear if users were looking into mutual funds from Sweden. This shows the power of community.</p>\n<p>Having the platform be <em>open source</em> is key.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"gpt-as-the-interface\">GPT as the interface<a href=\"https://didierlopes.com/blog/the-future-of-finance-with-open-source-and-ai#gpt-as-the-interface\" class=\"hash-link\" aria-label=\"Direct link to GPT as the interface\" title=\"Direct link to GPT as the interface\">​</a></h2>\n<p><strong>One of the hedges that incumbents have is the fact that they have been around for a very long time and spent a lot on educating users about their product.</strong> As a result, users are used to their platform. This makes them harder to switch to an unknown product. This is also why a product needs to be 10x better than competition for users to switch.</p>\n<p><strong>However, what if there was no learning curve?</strong> What if you could use a product for the first time and knew how to access all the data without spending any time reading the documentation. <strong>In essence, the educational incumbent advantage would become obsolete.</strong></p>\n<p>With the new LLM advancements, such as <a href=\"https://chat.openai.com/chat\" target=\"_blank\" rel=\"noopener noreferrer\">ChatGPT</a>. We are not far from this reality.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"cool1\" src=\"https://didierlopes.com/assets/images/2022-12-04-the-future-of-finance-with-open-source-and-ai_2-c4cf2082079e8604319a8d03e999f330.webp\" width=\"600\" height=\"327\" class=\"img_ev3q\"></p>\n<p>Plus, if this is built on top of an open source project it means that the <strong>community can help in improving the model</strong> by providing more training data (e.g. provide a text as input and the corresponding command as output) or even confirm whether or not the chart that pops up was accurate. In addition, along with data sources you can imagine that the community could start contributing with new languages for the GPT model.</p>\n<p>You can easily imagine that such interface would work well with a speech recognition model (something like <a href=\"https://github.com/openai/whisper\" target=\"_blank\" rel=\"noopener noreferrer\">whisper</a> but that allowed real-time).</p>\n<p><strong>This makes using a new investment research platform easy, but more importantly makes retrieving information much faster and efficient.</strong></p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"gpt-to-build-investment-research-reports\">GPT to build investment research reports<a href=\"https://didierlopes.com/blog/the-future-of-finance-with-open-source-and-ai#gpt-to-build-investment-research-reports\" class=\"hash-link\" aria-label=\"Direct link to GPT to build investment research reports\" title=\"Direct link to GPT to build investment research reports\">​</a></h2>\n<p>One of the new features that were announced with <a href=\"https://openbb.co/blog/openbb-terminal-2-acai\" target=\"_blank\" rel=\"noopener noreferrer\">OpenBB Terminal 2.0</a> was the automated reports generation that utilizes <a href=\"https://github.com/nteract/papermill\" target=\"_blank\" rel=\"noopener noreferrer\">papermill</a> to leverage jupyter notebook templates.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"cool2\" src=\"https://didierlopes.com/assets/images/2022-12-04-the-future-of-finance-with-open-source-and-ai_3-690c999c5f9afc603a4770306439efec.webp\" width=\"1920\" height=\"1080\" class=\"img_ev3q\"></p>\n<p>As it stands creating one of these notebook templates requires some coding skills and reading <a href=\"https://docs.openbb.co/\" target=\"_blank\" rel=\"noopener noreferrer\">OpenBB documentation</a> to understand how to retrieve the data of interest providing the correct function and necessary arguments.</p>\n<p><strong>But, for a second, imagine if you could build these notebook templates with almost no-code?</strong></p>\n<p>The proof-of-concept below in combination with the automated report generation should allow you to further understand the breakthrough that we may accomplish in the following few months.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2022-12-04-the-future-of-finance-with-open-source-and-ai_4-14dc3286e56edad0fa23aa855a3361f8.webp\" width=\"1400\" height=\"1204\" class=\"img_ev3q\"></p>\n<p><strong>My prediction is that open source + AI will disrupt the financial sector in the upcoming years.</strong></p>\n<p><a href=\"https://openbb.co/\" target=\"_blank\" rel=\"noopener noreferrer\">OpenBB</a> will be leading that wave.</p>\n<p>Thanks for reading!</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/the-future-of-finance-with-open-source-and-ai",
            "title": "The future of finance with open source and AI",
            "summary": "The future of finance is being reshaped by open source and AI. This post discusses the potential of these technologies in disrupting the financial industry, the advantages of open source, and the role of AI in user interface.",
            "date_modified": "2022-12-04T00:00:00.000Z",
            "tags": [
                "open-source",
                "ai",
                "finance",
                "future"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/bloomberg-terminal-is-no-more-openbb-terminal-2-0-has-just-been-released",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2022-11-29-bloomberg-terminal-is-no-more-openbb-terminal-2-0-has-just-been-released.webp\"></p>\n<br>\n<p>OpenBB Terminal 2.0 has been released. This blog post discusses the new features and improvements, including the release of OpenBB SDK, a state-of-the-art AI/ML toolkit for the financial industry, and the vision for a community-driven investment research platform.</p>\n<p>The open source code is available <a href=\"https://github.com/DidierRLopes/GamestonkTerminal\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>Almost 2 years ago, I started building my own investment research platform. 2 months later I named it Gamestonk Terminal, made it open source and shared it on Reddit. The rest is history.</p>\n<p>Since then, we surpassed <a href=\"https://github.com/OpenBB-finance/OpenBBTerminal\" target=\"_blank\" rel=\"noopener noreferrer\">17,800 stars on Github</a>. Raised $ 8.8 million in our seed round. Build a very competitive team and our OpenBB brand is now recognized by most in the financial space. You can read more about our story <a href=\"https://openbb.co/blog/gme-didnt-take-me-to-the-moon-but-gamestonk-terminal-did\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<p><strong>Our mission to democratize investment research has not changed.</strong> Over the past few months we have been heads down and building and today I'm excited to share with you the announcement of OpenBB Terminal 2.0.</p>\n<p>The headline is:</p>\n<blockquote>\n<p><em>OpenBB Terminal 2.0 is more than an application, it's a platform.</em></p>\n</blockquote>\n<br>\n<p>A summary:</p>\n<ul>\n<li>We are releasing OpenBB SDK which allows developers to use a single API to access the world's raw financial data in order to build their own products / dashboards.</li>\n</ul>\n<p>The SDK will allow users to create report templates in a matter of minutes and run them for custom tickers at any time in a matter of seconds; Instead of spending hours and starting a report from scratch every single time. We envision a world where the community can share these and help each other at becoming better investors.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2022-11-29-bloomberg-terminal-is-no-more-openbb-terminal-2-0-has-just-been-released_1-3908ee29c3aa262b5f0c90074dd2888e.webp\" width=\"902\" height=\"510\" class=\"img_ev3q\"></p>\n<ul>\n<li>We are also bringing a state-of-the-art AI / ML toolkit to the financial industry, to be used alongside all the data sources our platform has access to (stocks, crypto, NFTs, options, forex, ETFs, mutual funds, macro economic data and even alternative data).</li>\n</ul>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2022-11-29-bloomberg-terminal-is-no-more-openbb-terminal-2-0-has-just-been-released_2-b3c25c72abc9b34c0146b9fb19952037.webp\" width=\"1400\" height=\"873\" class=\"img_ev3q\"></p>\n<p>For more information, you can read our announcement here: <a href=\"https://openbb.co/blog/openbb-terminal-2-acai\" target=\"_blank\" rel=\"noopener noreferrer\">https://openbb.co/blog/openbb-terminal-2-acai</a></p>\n<p>Or even better, watch the announcement <a href=\"https://openbb.co/blog/openbb-terminal-2-event\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>!</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/bloomberg-terminal-is-no-more-openbb-terminal-2-0-has-just-been-released",
            "title": "Bloomberg Terminal is no more. OpenBB Terminal 2.0 has just been released.",
            "summary": "OpenBB Terminal 2.0 has been released. This blog post discusses the new features and improvements, including the release of OpenBB SDK, a state-of-the-art AI/ML toolkit for the financial industry, and the vision for a community-driven investment research platform.",
            "date_modified": "2022-11-29T00:00:00.000Z",
            "tags": [
                "openbb",
                "product-launch",
                "investment-research",
                "sdk",
                "api",
                "ai",
                "ml",
                "open-source",
                "fintech"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/sweepstake-world-cup-2022-for-your-startup-team",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2022-11-26-sweepstake-world-cup-2022-for-your-startup-team.webp\"></p>\n<br>\n<p>In this blogpost, we share how we organized a World Cup 2022 sweepstake for our startup team as a team building activity, and how we built a slack bot to facilitate discussions around the event.</p>\n<p>The open source code is available <a href=\"https://github.com/DidierRLopes/worldcup2022-sweepstake-slackbot\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>At <a href=\"https://openbb.co/\" target=\"_blank\" rel=\"noopener noreferrer\">OpenBB</a>, the team puts in so much hard work for <a href=\"https://github.com/OpenBB-finance/OpenBBTerminal\" target=\"_blank\" rel=\"noopener noreferrer\">our product</a> that doing a team event is like a breath of fresh air. With the World Cup 2022 now taking place and more than half of the team being from Europe (where football is the main sport), we thought that it would be nice to run an OpenBB sweepstake.</p>\n<p>We decided to offer a prize to the teams that end up on the podium. 1st place gets X, 2nd place gets Y and 3rd place gets Z - with $ X &gt; $ Y &gt; $Z.</p>\n<p>The next step was to assign teams to each employee, so at the end of our all hands meeting we did just that. For that we used this free website: <a href=\"https://spinnerwheel.com/fifa-world-cup-sweepstake-generator\" target=\"_blank\" rel=\"noopener noreferrer\">https://spinnerwheel.com/fifa-world-cup-sweepstake-generator</a>.</p>\n<p>This allowed us to spin the wheel of team members and then spin wheel of countries, and get a 1:1 match — it was quite funny to have everyone involved and see the reactions as the wheel was slowing down.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2022-11-26-sweepstake-world-cup-2022-for-your-startup-team_1-76165b5d73997f0ab04f21b9781f3582.webp\" width=\"1400\" height=\"946\" class=\"img_ev3q\"></p>\n<p><strong>Most companies stop here.</strong></p>\n<p>...</p>\n<p>The best part about the sweepstake for me, is that the team members that don't usually interact with each other on a day to day basis have the opportunity to talk amongst themselves for this.</p>\n<p>So, to encourage these team interactions, the first step was to create a slack channel #worldcup-2022 that we could use to discuss each game.</p>\n<p><strong>But that isn't enough</strong>, because sometimes you require a trigger to start a discussion about the results and the next fixtures.</p>\n<p>I looked for a slack bot that achieved this, but <strong>I didn't find one</strong>.</p>\n<p>So I built one using Python which you can find <a href=\"https://github.com/DidierRLopes/worldcup2022-sweepstake-slackbot\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<p>This is the notification that the #worldcup-2022 receives everyday after all the matches have been played.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2022-11-26-sweepstake-world-cup-2022-for-your-startup-team_2-e5523c3468fd5e6c3ad6d2f4f418d09b.webp\" width=\"1240\" height=\"688\" class=\"img_ev3q\"></p>\n<p>The outcome has been great so far! Our team engagement is even higher than usual and we see team members that don't work directly with each other having the opportunity to get to know others better.</p>\n<p>If you want to do the same for your team, follow the instructions highlighted <a href=\"https://github.com/DidierRLopes/worldcup2022-sweepstake-slackbot\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<p>Any feedback is appreciated!</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/sweepstake-world-cup-2022-for-your-startup-team",
            "title": "Sweepstake World Cup 2022 for your startup team",
            "summary": "In this blogpost, we share how we organized a World Cup 2022 sweepstake for our startup team as a team building activity, and how we built a slack bot to facilitate discussions around the event.",
            "date_modified": "2022-11-26T00:00:00.000Z",
            "tags": [
                "team-building",
                "startup-culture",
                "world-cup",
                "sweepstake",
                "slack-bot",
                "python",
                "side-project"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/5-steps-i-used-to-change-my-job-title-in-less-than-1-year",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2022-11-14-5-steps-i-used-to-change-my-job-title-in-less-than-1-year_1.webp\"></p>\n<br>\n<p>This blog post outlines the five steps I took to change my job title from an Embedded Firmware Engineer to a Sensor Fusion Engineer in less than a year. It provides a roadmap for others who may be looking to make a similar career transition.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>In March 2020, I joined a startup as an Embedded Firmware Engineer. The startup's product focuses on smart running insoles with lightweight trackers that fit any running shoes.</p>\n<p>The company was small, and the firmware team was myself and 2 Senior Embedded Firmware Engineers.</p>\n<p>What I liked the most about this team was that our interests complemented each other very well. One of the Senior Embedded Firmware Engineers was very strong at wireless communications (BLE, ANT) while the other was great at communication protocols (SPI, I2C). On my end, my strength was from my MSc in Control Systems and my past experience with GNSS. In addition, I had a very high interest in learning about Inertial Navigation System (INS). My goal was to become a Sensor Fusion Engineer.</p>\n<p>So what did I do to become a Sensor Fusion Engineer?</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"declare-your-intent\">Declare your intent<a href=\"https://didierlopes.com/blog/5-steps-i-used-to-change-my-job-title-in-less-than-1-year#declare-your-intent\" class=\"hash-link\" aria-label=\"Direct link to Declare your intent\" title=\"Direct link to Declare your intent\">​</a></h2>\n<p>Since day 1 in the company, my team lead knew that my goal was to become a Sensor Fusion Engineer.</p>\n<p>This is very important, as your manager can keep this in the back of their mind when assigning tasks to you. For instance, my team lead was giving me a lot of material around the way our product processed external samples as this was critical to the INS.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"define-a-roadmap\">Define a roadmap<a href=\"https://didierlopes.com/blog/5-steps-i-used-to-change-my-job-title-in-less-than-1-year#define-a-roadmap\" class=\"hash-link\" aria-label=\"Direct link to Define a roadmap\" title=\"Direct link to Define a roadmap\">​</a></h2>\n<p>I asked my manager: \"What do I need to do to be recognized as a Sensor Fusion Engineer\".</p>\n<p>Knowing about the matter is not enough, you want to have the credentials so that you can jump faster in your career.</p>\n<p>My team lead was not aware of the capabilities I would need to have to become a Sensor Fusion Engineer, so he spent quite some time doing due diligence on this. Good managers will go out of their way to help you grow.</p>\n<p>After some time, we discussed what I would need to do at the company to be recognized as Sensor Fusion Engineer and built a roadmap in order to get there.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"work-hard\">Work hard<a href=\"https://didierlopes.com/blog/5-steps-i-used-to-change-my-job-title-in-less-than-1-year#work-hard\" class=\"hash-link\" aria-label=\"Direct link to Work hard\" title=\"Direct link to Work hard\">​</a></h2>\n<p>Work extremely hard towards that roadmap.</p>\n<p>I was not only working towards that roadmap, but I was also working towards it at 2.5x the average speed. I was working 80h — 100h / weeks during that time.</p>\n<p>I was being pulled into all meetings that discussed sensor fusion, I was reading old documentation to understand the decisions that I made, I was reading codebase and questioning all code (which allowed me to find some issues) and I was taking online courses on top of this.</p>\n<p>More importantly, I was experimenting with the product. Theory will only help you so much, you need to get your hands dirty or you will never be able to fully master a skill.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"frequently-revise-your-roadmap\">Frequently revise your roadmap<a href=\"https://didierlopes.com/blog/5-steps-i-used-to-change-my-job-title-in-less-than-1-year#frequently-revise-your-roadmap\" class=\"hash-link\" aria-label=\"Direct link to Frequently revise your roadmap\" title=\"Direct link to Frequently revise your roadmap\">​</a></h2>\n<p>Throughout all my 1:1 with my manager, we always revisited the roadmap — even if briefly. This made sure that he knew how serious I was about this topic, and allowed me to demonstrate my progress.</p>\n<p>This also allowed myself to look back and realize my own progress. I would spend time educating him on what I had learned and how we could apply that in our product, including some simulations I had done in Python.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"prove-yourself\">Prove yourself<a href=\"https://didierlopes.com/blog/5-steps-i-used-to-change-my-job-title-in-less-than-1-year#prove-yourself\" class=\"hash-link\" aria-label=\"Direct link to Prove yourself\" title=\"Direct link to Prove yourself\">​</a></h2>\n<p>Don't miss an opportunity to prove yourself.</p>\n<p>This is the most critical point, you need to prove that you are capable of delivering by actually demonstrating a real example.</p>\n<p>This is the egg or chicken first problem. When you don't have the initial experience, your company won't trust you to apply your knowledge. But if your company doesn't give you the chance you will never get the experience.</p>\n<p>In our case, users started getting weird jumps in altitude reported by the trackers. And we needed to figure out the issue fast as this was increasing the churn. I immediately knew I was able to solve this, and knew I had to grab this opportunity.</p>\n<p>Our trackers were not taking the GPS location in the estimation of user altitude, and I knew that considering that would substantially improve the estimation as the altitude has less chances to change drastically over a small distance.</p>\n<p>Finally, my degree and hundreds of hours of work were paying off. That day, I wrote our C/C++ altitude estimation algorithm in Python and provided with an input that had a spurious jump in pressure readings — i.e. I recreated how the issue was happening.</p>\n<p>I proceeded to implement a Kalman Filter solution to consider GPS readings as well, and the result was a massive improvement. The jump in altitude was non-existant now.</p>\n<p>In the daily standup the next day, I had accomplished most of my tasks for the sprint and asked the product owner if I could take a shot at fixing the altitude issue. He was a bit hesitant, but I had a notebook ready to show the problem recreated and my proposed solution in Python.</p>\n<p>He accepted and gave me the next 3 days to work on it and to present results on Monday. I didn't sleep until that Monday. Implementing from Python to C++ was the easy part. The hard part was debugging + optimizing the weights of the Kalman Filter.</p>\n<p>I was touching the code. Performing an over the air upgrade. Going outside for a run in a track with a bridge where I knew the altitude. Analyzing results at home. Iterate.</p>\n<p>Monday arrived and I presented results, and they looked so much better. The proposed solution was accepted. Our INS algorithm hadn't changed in a long time, so a lot of testing was needed.</p>\n<p>After that, the company accepted to offer me the title of Sensor Fusion engineer. Without a pay rise, but that was fine as for me it was about speeding up my career.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"conclusion\">Conclusion<a href=\"https://didierlopes.com/blog/5-steps-i-used-to-change-my-job-title-in-less-than-1-year#conclusion\" class=\"hash-link\" aria-label=\"Direct link to Conclusion\" title=\"Direct link to Conclusion\">​</a></h2>\n<ul>\n<li>Declare intent</li>\n<li>Define roadmap</li>\n<li>Work towards that roadmap</li>\n<li>Frequently revise roadmap</li>\n<li>Don't miss an opportunity to prove yourself</li>\n</ul>\n<p><strong>Note:</strong> If the company doesn't give you a chance to prove yourself, you should interview for that position with other companies. And if another company offers you that job, you will have the leverage that another company perceives you as that.</p>\n<p>I like <a href=\"https://youtube.com/shorts/x71Rm0MWVHY?si=BvtmjrE31d6U1bpV\" target=\"_blank\" rel=\"noopener noreferrer\">this video</a> about understanding your market value. And I think it can be extended in terms of your skillset if you want to change your role.</p>\n<p>Feedback as always is welcome :)</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/5-steps-i-used-to-change-my-job-title-in-less-than-1-year",
            "title": "5 steps I used to change my job title in less than 1 year",
            "summary": "This blog post outlines the five steps I took to change my job title from an Embedded Firmware Engineer to a Sensor Fusion Engineer in less than a year. It provides a roadmap for others who may be looking to make a similar career transition.",
            "date_modified": "2022-11-14T00:00:00.000Z",
            "tags": [
                "career-path",
                "career-growth",
                "job-title",
                "promotion",
                "skill-development",
                "self-improvement",
                "personal-story",
                "hard-work",
                "engineering"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/how-to-grow-your-open-source-community-from-scratch.md",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2022-11-10-how-to-grow-your-open-source-community-from-scratch_1.webp\"></p>\n<br>\n<p>Growing an open source community from scratch is a challenging task. This blogpost shares insights and strategies on how to effectively build and manage an open source community, using the example of the OpenBB Terminal project.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"project-naming\">Project naming<a href=\"https://didierlopes.com/blog/how-to-grow-your-open-source-community-from-scratch.md#project-naming\" class=\"hash-link\" aria-label=\"Direct link to Project naming\" title=\"Direct link to Project naming\">​</a></h3>\n<p>The name should be short, memorable, unique and related with the project.</p>\n<p>When I started what we call OpenBB Terminal today, the name of the project was “Stock Market Bot” or something silly like that. I knew that wouldn’t be the last name, but I didn’t have any inspiration and in the meantime I was focused on building the platform.</p>\n<p>I am an Elon Musk fan, and was a GameStop investor. This meant that once I saw <a href=\"https://twitter.com/elonmusk/status/1354174279894642703\" target=\"_blank\" rel=\"noopener noreferrer\">this tweet</a> — I didn’t blink twice and knew this was the name I was waiting for.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2022-11-10-how-to-grow-your-open-source-community-from-scratch-af259136862debe3593270e10cde5cec.webp\" width=\"906\" height=\"551\" class=\"img_ev3q\"></p>\n<p>That’s when Gamestonk Terminal (now OpenBB Terminal) was born.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"keep-the-project-private-until-mvp\">Keep the project private until MVP<a href=\"https://didierlopes.com/blog/how-to-grow-your-open-source-community-from-scratch.md#keep-the-project-private-until-mvp\" class=\"hash-link\" aria-label=\"Direct link to Keep the project private until MVP\" title=\"Direct link to Keep the project private until MVP\">​</a></h3>\n<ul>\n<li>There will be less pressure than building in public, and you will be able to iterate much faster.</li>\n<li>No users asking for features or reporting bugs when MVP is still under development.</li>\n<li>Most importantly, this guarantees that when the users see the MVP they know where you are heading with the project.</li>\n</ul>\n<p>I worked on Gamestonk Terminal for 2 months on my own. The code architecture changed several times as I was in this experimental phase. And if you look into the source code I even committed API keys accidentally. But I had no pressure, so I was able to ship extremely fast.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"prepare-to-onboard-the-community\">Prepare to onboard the community<a href=\"https://didierlopes.com/blog/how-to-grow-your-open-source-community-from-scratch.md#prepare-to-onboard-the-community\" class=\"hash-link\" aria-label=\"Direct link to Prepare to onboard the community\" title=\"Direct link to Prepare to onboard the community\">​</a></h3>\n<ul>\n<li>Make the documentation standout (not only “getting started” but also “contributing”).</li>\n<li>Create “quick win” tickets that the community can address quickly.</li>\n<li>Start a group channel on Discord or Slack, which allows you to interact with contributors and discuss features / roadmap and keep them engaged.</li>\n<li>Mention “starring” the project. As simple as this sounds, this helps with growth as its easy to forget to star the project, even though you were interested in what you saw.</li>\n</ul>\n<p>Some people from our current team told me recently that they fell in love with the README of the project the first time they saw it. In particular with this quote:</p>\n<blockquote>\n<p><em>“Gamestonk Terminal is an awesome stock and crypto market terminal that has been developed for fun, while I saw my GME shares tanking. But hey, I like the stock.”</em></p>\n</blockquote>\n<br>\n<p>This allowed me to gain not only contributors, but maintainers. And nowadays, team members.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"change-the-project-visibility-to-public\">Change the project visibility to public<a href=\"https://didierlopes.com/blog/how-to-grow-your-open-source-community-from-scratch.md#change-the-project-visibility-to-public\" class=\"hash-link\" aria-label=\"Direct link to Change the project visibility to public\" title=\"Direct link to Change the project visibility to public\">​</a></h3>\n<ul>\n<li>This allows everyone to have a first look into the project, it’s the “Hello World” moment.</li>\n<li>When sharing the project, describe the problem you are trying to solve and make sure your audience relates with that problem.</li>\n<li>Share your project on relevant channels (e.g. Reddit, HackerNews, ProductHunt) — where your audience is.</li>\n</ul>\n<p>I have been building in open source for a while, without much success. Until Gamestonk Terminal.</p>\n<p>The difference? I shared Gamestonk Terminal on:</p>\n<ul>\n<li>Reddit r/SuperStonk — where the retail traders with the same issue as me were gathered</li>\n<li>Reddit r/python — where the community shares projects built in python</li>\n<li>HackerNews — where I leveraged the name of a known brand in the same industry and insinuated that my tool was similar but affordable. The title was: “<a href=\"https://news.ycombinator.com/item?id=26258773\" target=\"_blank\" rel=\"noopener noreferrer\">Can’t afford Bloomberg Terminal? No prob, I built the next best thing</a>”.</li>\n</ul>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"keep-developing-in-public\">Keep developing in public<a href=\"https://didierlopes.com/blog/how-to-grow-your-open-source-community-from-scratch.md#keep-developing-in-public\" class=\"hash-link\" aria-label=\"Direct link to Keep developing in public\" title=\"Direct link to Keep developing in public\">​</a></h3>\n<ul>\n<li>Keep the community updated on the roadmap and progress. You can do this by doing demos of what you have accomplished as you add new features (e.g. <a href=\"https://www.youtube.com/watch?v=fqGPK8OVHLk\" target=\"_blank\" rel=\"noopener noreferrer\">on YouTube</a> or <a href=\"https://twitter.com/didier_lopes/status/1567117888590340098\" target=\"_blank\" rel=\"noopener noreferrer\">on Twitter</a>) which allows the community to understand what sort of tasks you are working on, and what they would learn if they were to contribute. It basically gives the community a hindsight into what a contributor will be able to work on / achieve.</li>\n<li>Get early feedback and prioritise accordingly.</li>\n<li>Occasionally go back to the same channels (e.g. Reddit, Hackernews) to report progress. This guarantees that they know the project is not dead and helps your project staying relevant and on their minds.</li>\n<li>Develop in public through livestreams (e.g. <a href=\"https://www.youtube.com/watch?v=9BMI9cleTTg\" target=\"_blank\" rel=\"noopener noreferrer\">live Coding</a>) or by sharing what you are working on through social media (e.g. <a href=\"https://twitter.com/didier_lopes/status/1579414220256387072\" target=\"_blank\" rel=\"noopener noreferrer\">adding a futures menu</a>).</li>\n</ul>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>TL;DR: On how to grow your open source project:</p>\n<ul>\n<li>Project naming</li>\n<li>Keep project private until MVP</li>\n<li>Prepare to onboard the community</li>\n<li>Change the project visibility to public</li>\n<li>Keep developing in public</li>\n</ul><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/how-to-grow-your-open-source-community-from-scratch.md",
            "title": "How to grow your open source community from scratch",
            "summary": "Growing an open source community from scratch is a challenging task. This blogpost shares insights and strategies on how to effectively build and manage an open source community, using the example of the OpenBB Terminal project.",
            "date_modified": "2022-11-10T00:00:00.000Z",
            "tags": [
                "open-source",
                "community-building",
                "project-management",
                "openbb-terminal"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/how-to-learn-10x-faster-than-average",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2022-10-27-how-to-learn-10x-faster-than-average.webp\"></p>\n<br>\n<p>Learn how to accelerate your learning process and become 10x faster than average. This blog post provides practical steps to enhance your self-learning abilities and master new skills effectively.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>Everyone is a self learner. But people’s rhythm of self learning can be vastly different.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"have-a-good-reason-to-learn-this-new-skill\">Have a good reason to learn this new skill<a href=\"https://didierlopes.com/blog/how-to-learn-10x-faster-than-average#have-a-good-reason-to-learn-this-new-skill\" class=\"hash-link\" aria-label=\"Direct link to Have a good reason to learn this new skill\" title=\"Direct link to Have a good reason to learn this new skill\">​</a></h3>\n<p>What is the main fundamental reason why you want to learn this skill? If you don’t have a one sentence answer, you probably don’t need to learn it.</p>\n<p>University teaches you hundreds of topics that you end up not being good at because you have no interest in it.</p>\n<p>Avoid spending your precious time on developing a skill that you have no interest or purpose in. Avoid trends too for this reason.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"research-and-read-about-the-best-way-to-learn-the-basics\">Research and read about the best way to learn the basics<a href=\"https://didierlopes.com/blog/how-to-learn-10x-faster-than-average#research-and-read-about-the-best-way-to-learn-the-basics\" class=\"hash-link\" aria-label=\"Direct link to Research and read about the best way to learn the basics\" title=\"Direct link to Research and read about the best way to learn the basics\">​</a></h3>\n<p>This should take no longer than one afternoon. Avoid promoted content.</p>\n<p>Usually, you’re able to find a course/book/video that is acclaimed by the community to be the best to get started with.</p>\n<p>So we are looking for the equivalent of “Machine Learning from Andrew Ng” for the skill you want to master.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"consume-the-basics-like-your-life-depends-on-it\">Consume the basics like your life depends on it<a href=\"https://didierlopes.com/blog/how-to-learn-10x-faster-than-average#consume-the-basics-like-your-life-depends-on-it\" class=\"hash-link\" aria-label=\"Direct link to Consume the basics like your life depends on it\" title=\"Direct link to Consume the basics like your life depends on it\">​</a></h3>\n<p>This will be the foundation of all your subsequent learning in this new area. Put your phone away, and take notes.</p>\n<p>Revisit those notes, and if necessary go back in time to understand the basics.</p>\n<p>It took me above average time to finish Machine Learning from Andrew Ng.</p>\n<p>However, since this, whenever I learn or even think about AI problems this is now easier because of that laid out work.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"test-your-knowledge-with-a-real-problem-aka-get-your-hands-dirty\">Test your knowledge with a real problem (aka get your hands dirty)<a href=\"https://didierlopes.com/blog/how-to-learn-10x-faster-than-average#test-your-knowledge-with-a-real-problem-aka-get-your-hands-dirty\" class=\"hash-link\" aria-label=\"Direct link to Test your knowledge with a real problem (aka get your hands dirty)\" title=\"Direct link to Test your knowledge with a real problem (aka get your hands dirty)\">​</a></h3>\n<p>And no, I don’t mean do an exercise that you find online.</p>\n<p>Define a problem that you can solve with the skills you acquired and work on it.</p>\n<p>Don’t ask for the answer. Don’t Google for the solution, but Google for something that is a current impediment on your solution.</p>\n<p>If you are struggling on formulating the Google prompt, revisit your first notes on the skill.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"keep-learning-about-the-topic\">Keep learning about the topic<a href=\"https://didierlopes.com/blog/how-to-learn-10x-faster-than-average#keep-learning-about-the-topic\" class=\"hash-link\" aria-label=\"Direct link to Keep learning about the topic\" title=\"Direct link to Keep learning about the topic\">​</a></h3>\n<p>The getting started foundation will only get you so far. It’s likely that soon you will grow out of that and need to expand your knowledge.</p>\n<p>Don’t jump on this step too early. Make sure your basics are covered before you move on.</p>\n<p>Go back to the real problem you worked on, and see how the new learned skills could be applied for that same problem.</p>\n<p>If those skills aren’t necessarily in that first problem, it’s also a good sign. It’s a sign that you learned not only the skill but when it is and it isn’t used.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"iterate\">Iterate<a href=\"https://didierlopes.com/blog/how-to-learn-10x-faster-than-average#iterate\" class=\"hash-link\" aria-label=\"Direct link to Iterate\" title=\"Direct link to Iterate\">​</a></h3>\n<p>Keep iterating between using this new skill to solve a real problem and learning from courses/videos/books.</p>\n<p>There isn’t a “you made it” badge. But you know you did, once you’re able to look for a specific piece of information on a video/book to fill in the gap for something you needed for your real problem.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>TL;DR on how to learn 10x faster than average</p>\n<ol>\n<li>Have a good reason to learn this new skill.</li>\n<li>Research and read about the best way to learn the basics.</li>\n<li>Consume the basics like your life depended on it.</li>\n<li>Test your knowledge with a real problem.</li>\n<li>Keep learning about the topic.</li>\n<li>Iterate.</li>\n</ol><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/how-to-learn-10x-faster-than-average",
            "title": "How to learn 10x faster than average",
            "summary": "Learn how to accelerate your learning process and become 10x faster than average. This blog post provides practical steps to enhance your self-learning abilities and master new skills effectively.",
            "date_modified": "2022-10-27T00:00:00.000Z",
            "tags": [
                "learning",
                "self-improvement",
                "skills",
                "education"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/how-to-convert-a-twitter-thread-into-a-linkedin-carousel-in-seconds",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2022-10-23-how-to-convert-a-twitter-thread-into-a-linkedin-carousel-in-seconds.webp\"></p>\n<br>\n<p>In this blog post, I share how I built a Python tool that converts a Twitter thread into a LinkedIn carousel in seconds. This tool is open source and contributions for improvements are welcome.</p>\n<p>The open source code is available <a href=\"https://github.com/DidierRLopes/thread-to-carousel/tree/master\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>As content creators, it would be good if the same content could be utilised across every platform easily. Sometimes you need some tweaks based on audience, but often the same content is used across all platforms.</p>\n<p>I noticed recently that LinkedIn carousels have been picking a lot of traction, and given I have some nice Twitter threads (<a href=\"https://twitter.com/didier_lopes/status/1570731358204600323?s=20&amp;t=SAO9fD7FR7jeTE-6kem6Mg\" target=\"_blank\" rel=\"noopener noreferrer\">example</a>) I thought that it would be great if I could convert them into a LinkedIn carousel.</p>\n<p>So, I looked for free tools and didn't find anything good enough. I ended up using <a href=\"https://canvas.apps.chrome/\" target=\"_blank\" rel=\"noopener noreferrer\">canvas</a> to re-create the thread — which you can find <a href=\"https://www.linkedin.com/posts/didier-lopes_due-diligence-on-amt-using-openbb-terminal-activity-6977569279395176448-TFMn?utm_source=share&amp;utm_medium=member_desktop\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>. It worked well, but it was time consuming and for most cases, I don't want to be messing around with the design side of things.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2022-10-23-how-to-convert-a-twitter-thread-into-a-linkedin-carousel-in-seconds_1-495584d95392b92ddd8c40569a18b213.webp\" width=\"1078\" height=\"1076\" class=\"img_ev3q\"></p>\n<p>As a true software engineer and pythonist, I obtained the Twitter API keys and built a tool that would convert a Twitter thread into a LinkedIn carousel in a matter of seconds.</p>\n<p>And as usual, I open sourced it: <a href=\"https://github.com/DidierRLopes/thread-to-carousel\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/DidierRLopes/thread-to-carousel</a>.</p>\n<p>This tool is far from perfect, and a lot can be improved on the design side of things to: Recognize emojis; Highlight mentions; Change the size of the box based on the text; Better text placement when images attached; Better URL link display.</p>\n<p>The goal for me wasn't to build a perfect tool, but something easy enough that did the job. And, as the project is open source, I expect to have users contributing to the script so that it can be improved over time.</p>\n<p>Today I run it using:</p>\n<div class=\"language-console codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-console codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">python convert2carousel.py https://twitter.com/didier_lopes/status/1581247044228100096</span><br></span></code></pre></div></div>\n<p>And the result can be found <a href=\"https://www.linkedin.com/posts/didier-lopes_football-momentum-indicator-carousel-activity-6989972573782482944-nM9s?utm_source=share&amp;utm_medium=member_desktop\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2022-10-23-how-to-convert-a-twitter-thread-into-a-linkedin-carousel-in-seconds_2-2fb466daf80a78653c19ee1b4400efc8.webp\" width=\"1112\" height=\"1292\" class=\"img_ev3q\"></p>\n<p>Feel free to check the project here and I look forward to having contributors helping me improve it!</p>\n<p>As always, any feedback welcome 🙏🏽</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/how-to-convert-a-twitter-thread-into-a-linkedin-carousel-in-seconds",
            "title": "Twitter thread to LinkedIn carousel in python",
            "summary": "In this blog post, I share how I built a Python tool that converts a Twitter thread into a LinkedIn carousel in seconds. This tool is open source and contributions for improvements are welcome.",
            "date_modified": "2022-10-23T00:00:00.000Z",
            "tags": [
                "python",
                "linkedin",
                "twitter",
                "carousel",
                "content-creation",
                "automation",
                "api",
                "side-project"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/how-i-would-do-due-diligence-on-amt-using-openbb-terminal",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2022-10-20-how-i-would-do-due-diligence-on-amt-using-openbb-terminal.webp\"></p>\n<br>\n<p>This blog post provides a detailed walkthrough on how to conduct due diligence on $AMT using the OpenBB Terminal, a free and open source platform for financial data analysis.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>Last month someone on Twitter asked me to do a thread on how I would do due diligence on $AMT using the free and open source <a href=\"https://github.com/OpenBB-finance/OpenBBTerminal\" target=\"_blank\" rel=\"noopener noreferrer\">OpenBB Terminal</a>.</p>\n<p>Below I demonstrate what you can expect from using that platform.</p>\n<p>We could go much deeper, but this shows examples of output that you can expect. With over 800 commands and over 100 data sources, this is a very small subset of what you can achieve through this platform.</p>\n<p>In addition, this will only be in relation with stocks data, but the terminal also has access to options, crypto, ETFs, mutual funds, NFTs, macro economy, futures and even alternative data!</p>\n<p>More information on the platform and how to install it <a href=\"https://my.openbb.co/app/terminal/download\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<p>Strap in.</p>\n<div class=\"language-console codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-console codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">$ /stocks/load AMT/candle</span><br></span></code></pre></div></div>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2022-10-20-how-i-would-do-due-diligence-on-amt-using-openbb-terminal_1-19106ae7796bd8c2eb8ebf48fd2b0259.webp\" width=\"1400\" height=\"547\" class=\"img_ev3q\"></p>\n<div class=\"language-console codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-console codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">$ /stocks/fa/mktcap</span><br></span></code></pre></div></div>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2022-10-20-how-i-would-do-due-diligence-on-amt-using-openbb-terminal_2-c1314341746b9e489211126b58296aaa.webp\" width=\"1400\" height=\"547\" class=\"img_ev3q\"></p>\n<div class=\"language-console codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-console codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">$ /stocks/fa/mgmt</span><br></span></code></pre></div></div>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2022-10-20-how-i-would-do-due-diligence-on-amt-using-openbb-terminal_3-4647ba0c87c6ba3f2015d72871e33911.webp\" width=\"1400\" height=\"1294\" class=\"img_ev3q\"></p>\n<div class=\"language-console codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-console codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">$ /stocks/fa/income/balance/cash</span><br></span></code></pre></div></div>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2022-10-20-how-i-would-do-due-diligence-on-amt-using-openbb-terminal_4-e4b32588562de1356c50a506d078d8de.webp\" width=\"1216\" height=\"1920\" class=\"img_ev3q\"></p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2022-10-20-how-i-would-do-due-diligence-on-amt-using-openbb-terminal_5-12e05ff7a276b18479c7ecdce3401e8d.webp\" width=\"1368\" height=\"1198\" class=\"img_ev3q\"></p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2022-10-20-how-i-would-do-due-diligence-on-amt-using-openbb-terminal_6-aa1bff4f8bd8849853152f4fa6149bd1.webp\" width=\"1400\" height=\"1570\" class=\"img_ev3q\"></p>\n<div class=\"language-console codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-console codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">$ /stocks/fa/shrs</span><br></span></code></pre></div></div>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2022-10-20-how-i-would-do-due-diligence-on-amt-using-openbb-terminal_7-6ae875e2d9976fe0244a3f2acf1a3e26.webp\" width=\"1400\" height=\"1743\" class=\"img_ev3q\"></p>\n<div class=\"language-console codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-console codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">$ /stocks/fa/sust</span><br></span></code></pre></div></div>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2022-10-20-how-i-would-do-due-diligence-on-amt-using-openbb-terminal_8-9556151330af00a3533bdaaae651ce3b.webp\" width=\"620\" height=\"1698\" class=\"img_ev3q\"></p>\n<div class=\"language-console codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-console codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">$ /stocks/fa/divs</span><br></span></code></pre></div></div>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2022-10-20-how-i-would-do-due-diligence-on-amt-using-openbb-terminal_9-fb4fc2fe9d140aa8d19dfc80b8eb4a46.webp\" width=\"530\" height=\"1092\" class=\"img_ev3q\"></p>\n<div class=\"language-console codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-console codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">$ /stocks/fa/dcf</span><br></span></code></pre></div></div>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2022-10-20-how-i-would-do-due-diligence-on-amt-using-openbb-terminal_10-eef356cfd330418522a146526d86cd97.webp\" width=\"1400\" height=\"630\" class=\"img_ev3q\"></p>\n<div class=\"language-console codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-console codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">$ /stocks/ins/stats</span><br></span></code></pre></div></div>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2022-10-20-how-i-would-do-due-diligence-on-amt-using-openbb-terminal_11-d5be7f39debfa04c2f3a430576d50b92.webp\" width=\"1400\" height=\"746\" class=\"img_ev3q\"></p>\n<div class=\"language-console codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-console codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">$ /stocks/dps/psi</span><br></span></code></pre></div></div>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2022-10-20-how-i-would-do-due-diligence-on-amt-using-openbb-terminal_12-13378bd89cb3c0d38ee9548fe766121e.webp\" width=\"1400\" height=\"527\" class=\"img_ev3q\"></p>\n<div class=\"language-console codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-console codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">$ /stocks/gov/histcont</span><br></span></code></pre></div></div>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2022-10-20-how-i-would-do-due-diligence-on-amt-using-openbb-terminal_13-419935a08b78e634fb6718f134180464.webp\" width=\"1400\" height=\"547\" class=\"img_ev3q\"></p>\n<div class=\"language-console codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-console codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">$ /stocks/dd/rating</span><br></span></code></pre></div></div>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2022-10-20-how-i-would-do-due-diligence-on-amt-using-openbb-terminal_14-a81bf4954605df9d83ead4ef2754f019.webp\" width=\"1174\" height=\"474\" class=\"img_ev3q\"></p>\n<div class=\"language-console codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-console codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">$ /stocks/dd/pt</span><br></span></code></pre></div></div>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2022-10-20-how-i-would-do-due-diligence-on-amt-using-openbb-terminal_15-af503959c30f431cde6b2cff06354e43.webp\" width=\"1400\" height=\"547\" class=\"img_ev3q\"></p>\n<div class=\"language-console codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-console codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">$ /stocks/dd/est</span><br></span></code></pre></div></div>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2022-10-20-how-i-would-do-due-diligence-on-amt-using-openbb-terminal_16-a1a706106cace22086fc24254c89b1a4.webp\" width=\"978\" height=\"1706\" class=\"img_ev3q\"></p>\n<div class=\"language-console codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-console codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">$ /stocks/ta/sma</span><br></span></code></pre></div></div>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2022-10-20-how-i-would-do-due-diligence-on-amt-using-openbb-terminal_17-dd6e07f1cfad50fc62f31973598662dc.webp\" width=\"1400\" height=\"547\" class=\"img_ev3q\"></p>\n<div class=\"language-console codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-console codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">$ /stocks/ta/recom/summary</span><br></span></code></pre></div></div>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2022-10-20-how-i-would-do-due-diligence-on-amt-using-openbb-terminal_18-069bc46608c69d6e09b08adfb4e4767c.webp\" width=\"1156\" height=\"842\" class=\"img_ev3q\"></p>\n<div class=\"language-console codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-console codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">$ /stocks/ba/sentiment</span><br></span></code></pre></div></div>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2022-10-20-how-i-would-do-due-diligence-on-amt-using-openbb-terminal_19-6ae3a197f3a8454228083e857de223b3.webp\" width=\"1400\" height=\"737\" class=\"img_ev3q\"></p>\n<div class=\"language-console codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-console codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">$ /stocks/sia/metric tc</span><br></span></code></pre></div></div>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2022-10-20-how-i-would-do-due-diligence-on-amt-using-openbb-terminal_20-afe672e07601ef5c5fac370fa0106de1.webp\" width=\"1400\" height=\"539\" class=\"img_ev3q\"></p>\n<div class=\"language-console codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-console codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">$ /stocks/sia/metric fcf</span><br></span></code></pre></div></div>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2022-10-20-how-i-would-do-due-diligence-on-amt-using-openbb-terminal_21-ed58461a26ddcde9e2062fe718f3c1a6.webp\" width=\"1400\" height=\"539\" class=\"img_ev3q\"></p>\n<div class=\"language-console codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-console codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">$ /stocks/sia/vis oi</span><br></span></code></pre></div></div>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2022-10-20-how-i-would-do-due-diligence-on-amt-using-openbb-terminal_22-ded10cdd14a831e82c1aaf7dd4802b16.webp\" width=\"1400\" height=\"541\" class=\"img_ev3q\"></p>\n<div class=\"language-console codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-console codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">$ /stocks/ca/historical/hcorr</span><br></span></code></pre></div></div>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2022-10-20-how-i-would-do-due-diligence-on-amt-using-openbb-terminal_23-db53c786d0762f51641d08ba603ecb9b.webp\" width=\"1400\" height=\"535\" class=\"img_ev3q\"></p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2022-10-20-how-i-would-do-due-diligence-on-amt-using-openbb-terminal_24-28af4c310a1a38525e1a00e5c3c6dd07.webp\" width=\"1400\" height=\"547\" class=\"img_ev3q\"></p>\n<div class=\"language-console codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-console codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">$ /stocks/ca/cashflow/income/balance</span><br></span></code></pre></div></div>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2022-10-20-how-i-would-do-due-diligence-on-amt-using-openbb-terminal_25-0ca3cd90bb827a1ad44ebc673817a8d9.webp\" width=\"1302\" height=\"756\" class=\"img_ev3q\"></p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2022-10-20-how-i-would-do-due-diligence-on-amt-using-openbb-terminal_26-4a6593b3f155e6551b2a8e74319c77a7.webp\" width=\"1400\" height=\"1107\" class=\"img_ev3q\"></p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2022-10-20-how-i-would-do-due-diligence-on-amt-using-openbb-terminal_27-d5a88436d353a7a023bcc5c46b3cac88.webp\" width=\"1342\" height=\"1258\" class=\"img_ev3q\"></p>\n<p>I know this can be overwhelming information and it takes some time to run all these commands.</p>\n<p>Hence I created a <a href=\"https://github.com/OpenBB-finance/OpenBBTerminal/blob/main/openbb_terminal/miscellaneous/routines/due_diligence_stock.openbb\" target=\"_blank\" rel=\"noopener noreferrer\">script</a>. So now you can run all of these commands in one go, with:</p>\n<div class=\"language-console codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-console codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">$ /exe due_diligence_stock.openbb -i AMT</span><br></span></code></pre></div></div>\n<p>Any feedback is welcome!</p>\n<p>And if you want to ask questions about the product before installing it, feel free to join us on Discord here: <a href=\"https://openbb.co/discord\" target=\"_blank\" rel=\"noopener noreferrer\">https://openbb.co/discord</a></p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/how-i-would-do-due-diligence-on-amt-using-openbb-terminal",
            "title": "How I would do due diligence on $AMT using OpenBB Terminal",
            "summary": "This blog post provides a detailed walkthrough on how to conduct due diligence on $AMT using the OpenBB Terminal, a free and open source platform for financial data analysis.",
            "date_modified": "2022-10-20T00:00:00.000Z",
            "tags": [
                "openbb-terminal",
                "investment-research",
                "stocks",
                "due-diligence"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/stop-doing-your-cv-in-word-or-latex",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2022-10-15-stop-doing-your-cv-in-word-or-latex.webp\"></p>\n<br>\n<p>The future of CVs for engineers and developers lies within GitHub. This post discusses why GitHub profiles are becoming the new CVs and how they can provide a more comprehensive view of a candidate's skills and contributions.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>The purpose of a CV is to summarize someone’s career, qualifications and education. <strong>As an engineer or developer, I strongly believe that the future of CVs lies within GitHub.</strong></p>\n<p>In fact, GitHub has realized this and they now allow you to create your own “<em>profile page</em>” by creating a repository with the same name as your GitHub username. E.g. <a href=\"https://github.com/DidierRLopes\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/DidierRLopes</a></p>\n<p>In my humble opinion, this isn’t being talked enough. Previously, you needed a CV document to talk about your background, education, previous jobs and could rely on your GitHub profile to show your projects. With this update, CVs have become obsolete. When hiring for <a href=\"https://openbb.co/\" target=\"_blank\" rel=\"noopener noreferrer\">OpenBB</a>, I put a lot of weight into the public GitHub of each engineer.</p>\n<p>This is my current <a href=\"https://github.com/DidierRLopes\" target=\"_blank\" rel=\"noopener noreferrer\">GitHub profile page</a>.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2022-10-15-stop-doing-your-cv-in-word-or-latex_1-dcc4d7cc55c4c6b556a9831dbcd59789.webp\" width=\"1334\" height=\"1244\" class=\"img_ev3q\"></p>\n<p>My profile page is now much simpler since I’ve worked on my <a href=\"https://didierrlopes.github.io/personal-website/\" target=\"_blank\" rel=\"noopener noreferrer\">own personal website</a>, but you can see <a href=\"https://github.com/DidierRLopes/DidierRLopes/tree/98c27cfb087fc8ce6986f4ea8136e76ca14f145b\" target=\"_blank\" rel=\"noopener noreferrer\">here</a> what my GitHub profile page looked like before. Creating your own personalized website for me is the next step after GitHub, as you can be as creative as you want while showing off your coding skills.</p>\n<p>My repository is my way of showing the world what I can do on my own. From a blank sheet to a finalized project. <strong>Sometimes useful, sometimes for fun, but always with the intention to learn more and challenge myself.</strong></p>\n<p>The reason I think that GitHub profile’s are the CVs of the future for engineers/developers, is not only because you can now both talk about yourself in it and display your portfolio, but because of its open source nature.</p>\n<p>With products like: <a href=\"https://ossinsight.io/analyze/DidierRLopes\" target=\"_blank\" rel=\"noopener noreferrer\">https://ossinsight.io/analyze/DidierRLopes</a>, you will be able to dive deeper on engineering skills than ever before.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2022-10-15-stop-doing-your-cv-in-word-or-latex_2-2547d723e95479d4cf174d3a535a326d.webp\" width=\"1400\" height=\"742\" class=\"img_ev3q\"></p>\n<p>Companies will be able to assess a candidate based on their open source work:</p>\n<ul>\n<li>How do they interact with the community? What are their communication skills?</li>\n<li>Do they practice teamwork? And mentor more junior developers?</li>\n<li>Are they leaving comments in the code? Is their code readable in the first place?</li>\n<li>What about testing? Are they following good practices?</li>\n<li>What’s their time to reply to issues? Or to review PRs from peers?</li>\n<li>Activity? What are their working hour patterns like?</li>\n<li>…</li>\n</ul>\n<p>Imagine a world where everyone develops in the wild. You can see everything and be part of any project. You have your own profile, you talk with others through issues or PRs, you build together. There is no gender, no race, no nationality,.. people are conneced through projects they believe in. <strong>In essence, this is the developer metaverse, and I’m all here for it.</strong></p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2022-10-15-stop-doing-your-cv-in-word-or-latex_3-5f18f7fa5d067d6595c16589159e0ae0.webp\" width=\"1400\" height=\"939\" class=\"img_ev3q\"></p>\n<p><strong>EDIT:</strong> The reader should be aware that nowadays a properly formatted resume is still critical when added to a job board. This is because automated resume readers expect a certain format in order to recommend candidates to companies and vice-versa.</p>\n<p>Hope you enjoyed this post. As always, any feedback welcome! 🙏</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/stop-doing-your-cv-in-word-or-latex",
            "title": "Stop doing your CV in Word or LaTeX",
            "summary": "The future of CVs for engineers and developers lies within GitHub. This post discusses why GitHub profiles are becoming the new CVs and how they can provide a more comprehensive view of a candidate's skills and contributions.",
            "date_modified": "2022-10-15T00:00:00.000Z",
            "tags": [
                "github",
                "cv",
                "career",
                "open-source",
                "developer"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/why-you-should-drop-yfinance-api-and-adopt-openbb-sdk",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2022-10-01-why-you-should-drop-yfinance-api-and-adopt-openbb-sdk.webp\"></p>\n<br>\n<p>Why you should consider switching from yfinance API to OpenBB SDK for financial data retrieval. OpenBB SDK offers access to multiple data sources, potential for unlimited data, and incentives for data source partners.</p>\n<p>The open source code is available <a href=\"https://github.com/DidierRLopes/GamestonkTerminal\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>OpenBB SDK will be released later this month 👀.</p>\n<p><a href=\"https://github.com/ranaroussi/yfinance\" target=\"_blank\" rel=\"noopener noreferrer\">yfinance API</a> is an unofficial (not affiliated) API around <a href=\"https://finance.yahoo.com/\" target=\"_blank\" rel=\"noopener noreferrer\">Yahoo Finance website</a>.</p>\n<p>Although it is used in over 12,600 projects on GitHub and is downloaded on average 90,000 per week. This is still an unofficial wrapper. As you can see from Yahoo Finance website, it uses an ad revenue business model. This means that Yahoo Finance doesn’t has any incentive from having users utilizing it through Yfinance API.</p>\n<p>If one day Yahoo Finance website adds a paywall through an API key, then Yahoo Finance would:</p>\n<ol>\n<li>Either become obsolete</li>\n<li>Or adopt the same architecture of OpenBB where an API key from a data source is necessary</li>\n</ol>\n<br>\n<p>Regardless, Yfinance API retrieves data that exists on a third-party website: Yahoo Finance website. This means that this API is limited by the data Yahoo Finance is currently paying for redistribution. And thus, users get only what data is supported through the website.</p>\n<p>On the other hand, OpenBB SDK allows you to retrieve data from over 50 different APIs (and growing). With yfinance being one of these APIs.</p>\n<p>Since OpenBB SDK requires API keys from most of the data sources, these have incentives to partner with OpenBB. Because:</p>\n<ol>\n<li>Marketing opportunity due to significant larger pool of users</li>\n<li>New revenue stream</li>\n</ol>\n<br>\n<p>In essence, Yfinance API:</p>\n<ul>\n<li>Not officially supported by Yahoo Finance</li>\n<li>No incentive for Yahoo Finance</li>\n<li>Limited data by what Yahoo Finance displays</li>\n<li>May become obsolete</li>\n</ul>\n<p>On the other hand, OpenBB SDK:</p>\n<ul>\n<li>Marketing for new data sources</li>\n<li>New revenue stream for partners through premium API keys</li>\n<li>(Almost) unlimited data - open source project that keeps on adding new data sources</li>\n<li>Multiple data sources for same data (user has choices)</li>\n</ul>\n<p>As counter-intuitive as it sounds:</p>\n<p>The shutting down of yfinance API (which is one of the data sources that OpenBB SDK has access to) would be beneficial to OpenBB adoption. This is because users would need to migrate to OpenBB SDK as that’s the most mature and maintained open source financial API.</p>\n<p>If you have any questions, feel free to drop me a message!</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/why-you-should-drop-yfinance-api-and-adopt-openbb-sdk",
            "title": "Why you should drop yfinance API and adopt OpenBB SDK",
            "summary": "Why you should consider switching from yfinance API to OpenBB SDK for financial data retrieval. OpenBB SDK offers access to multiple data sources, potential for unlimited data, and incentives for data source partners.",
            "date_modified": "2022-10-01T00:00:00.000Z",
            "tags": [
                "openbb-sdk",
                "yfinance-api",
                "financial-data",
                "apis",
                "open-source"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/how-i-became-ceo-of-openbb",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2022-08-14-how-i-became-ceo-of-openbb.webp\"></p>\n<br>\n<p>This post talks about my story of becoming the CEO of OpenBB, the company behind the fastest growing open source project in&nbsp;finance.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>Both my parents are Portuguese and emigrated to Switzerland for better conditions. This is where my brother and I were born. We moved back to our small hometown in Portugal when I was 8 years old.</p>\n<p>When I was 21 years old I moved to London to pursue my MSc in control systems at the Imperial College. I also joined a semiconductor company as a Software Design Engineer.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"ezgif com-optimize (5)\" src=\"https://didierlopes.com/assets/images/2022-08-14-how-i-became-ceo-of-openbb_1-702f35679d9ec549c054746afdfdc07b.webp\" width=\"720\" height=\"720\" class=\"img_ev3q\"></p>\n<p>In my spare time I learned Python so I could become more proficient in machine learning and artificial intelligence. When my mathematics professor learned of my interest in Python he challenged me to write the <a href=\"https://github.com/DidierRLopes/UnivariateTimeSeriesForecast\" target=\"_blank\" rel=\"noopener noreferrer\">code behind his PhD thesis</a> on \"<em>Data Science in the Modeling and Forecasting of Financial Time Series: from Classic methodologies to Deep Learning</em>\" which combined open source, ML/AI and finance. This was when I first started to realize my passion for financial data.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2022-08-14-how-i-became-ceo-of-openbb_2-7d3778f122c7c2c142dad4c507d27c12.webp\" width=\"1194\" height=\"744\" class=\"img_ev3q\"></p>\n<p>I was inspired by books like \"<em>Rich dad Poor dad</em>\" which allowed me to understand that the only way to build true generational wealth is through investing. Now that I started to accumulate more savings through my professional pursuits, and with my finance interest increasing from my thesis work, I wanted to invest my own capital.</p>\n<p>What I learned was that investing was a highly cumbersome process. Unlike coding where the tooling (e.g. VSCode) is optimized for efficiency and allows us to automate a lot of processes, investing was highly inefficient and impossible to automate.</p>\n<p>I was spending hours doing my own investment research (multiple tabs open researching several different sources on a ticker, screenshot the data to put on a document or share with friends, write my thoughts, and repeat), and this had to be done for every single ticker at different instances of time otherwise the data would become irrelevant.</p>\n<p>I learned from Reddit users how they gained insights and performed due diligence. I quickly realized their \"workflow\" was just as inefficient as mine. I concluded that the only aspect of research that should require user input is the interpretation. As far as I was concerned, all data gathering should be automated.</p>\n<p>I began investigating potential investment research tools that allowed automation and couldn't find any, not even the mythical $24k/year Bloomberg terminal. I looked for platforms on GitHub where I could build on top of with no success.</p>\n<p>During Covid Christmas break, the flight to visit my parents was cancelled, so I ended up staying at home and sketching/building what would become my own investment research platform. I noticed that there were hundreds of data providers offering free data tiers where the data provided didn't correlate with each other. If I wanted access to paid datasets or more requests per minute it would be as simple as to upgrade my API key to a paid plan.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2022-08-14-how-i-became-ceo-of-openbb_3-bdd7a4412f6b80f59f8b56c426a5aec9.webp\" width=\"838\" height=\"581\" class=\"img_ev3q\"></p>\n<p>Over the next two months I built a python based command line interface in my spare time for and released the first lines of code as Open Source under the name \"Gamestonk Terminal\" since I was an investor in Gamestop and Elon Musk had recently tweeted his now infamous <a href=\"https://twitter.com/elonmusk/status/1354174279894642703?s=20\" target=\"_blank\" rel=\"noopener noreferrer\">\"Gamestonk\" tweet</a>.</p>\n<p>The project went viral in a couple of minutes on <a href=\"https://www.reddit.com/r/Python/comments/m515yk/gamestonk_terminal_the_equivalent_to_an/\" target=\"_blank\" rel=\"noopener noreferrer\">Reddit</a> and <a href=\"https://news.ycombinator.com/item?id=26258773\" target=\"_blank\" rel=\"noopener noreferrer\">HackerNews</a>. In under 24h we had over 4,000 stars on <a href=\"https://github.com/OpenBB-finance/OpenBBTerminal\" target=\"_blank\" rel=\"noopener noreferrer\">GitHub</a>, and hundreds of messages requesting features, thanking me for the tool, or reporting bugs.</p>\n<p>The number of issues and feature requests was overwhelming for a single person working part-time, so I created a <a href=\"https://openbb.co/discord\" target=\"_blank\" rel=\"noopener noreferrer\">Discord group</a> and started building a community of users. Many of those same first users went on to become core maintainers of the project. The community started adding new data sources, new features and even new asset classes to the project - soon after we were supporting crypto, ETFs, options, forex, and macro economy.</p>\n<p>My goal was never to build a business/company with this product. My motivation was to create a better investment research platform that was unavailable until then. When we got approached by JJ (from OSS Capital), it was a no-brainer to create OpenBB, as this would allow me to accelerate the product vision and build the world's leading investment research platform.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/how-i-became-ceo-of-openbb",
            "title": "How I became CEO of OpenBB",
            "summary": "This post talks about my story of becoming the CEO of OpenBB, the company behind the fastest growing open source project in finance.",
            "date_modified": "2022-08-14T00:00:00.000Z",
            "tags": [
                "openbb",
                "ceo",
                "founder-story",
                "origin-story",
                "startup",
                "open-source",
                "career-path",
                "entrepreneurship",
                "side-project"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/web3-symbols-and-community",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2022-06-28-web3-symbols-and-community.webp\"></p>\n<br>\n<p>This blog post discusses the importance of strong communities in the Web 3.0 space, the role of decentralization, and how voting frameworks based on smart contracts can empower users.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>If you have been paying attention to the Web 3.0 space, you should have realized that most of the projects in the space rely on strong communities.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"why-on-web-30\">Why on Web 3.0?<a href=\"https://didierlopes.com/blog/web3-symbols-and-community#why-on-web-30\" class=\"hash-link\" aria-label=\"Direct link to Why on Web 3.0?\" title=\"Direct link to Why on Web 3.0?\">​</a></h3>\n<p>On a centralized concept (Web 2), there is usually a regulatory entity that decides whether something is True or False on a project/product. This means that there’s a single centralized company responsible for making a decision and users must trust that this entity is acting on their best interests.</p>\n<p>Furthermore, the users do not stand to win anything whether the decision is True or False. They may identify more with one of the outcomes, but there is no personal incentive to the user. Even if a user can relate with the outcomes they never feel a sense of belonging, as deep down they are aware that their opinion is not being taken into account.</p>\n<p>On a decentralized concept (Web 3), the story is the very different. A decentralized community is responsible for deciding the True or False, based on a voting framework defined a-priori. This means that the group of users, based on smart contracts executed on the blockchain, can vote on a particular decision. <strong>This is where the importance of a strong community kicks in.</strong></p>\n<p>On Web 2 the users must trust that such entity is acting on user’s best interests. That trust, on Web 3, occurs in form of a strong community. The best way for a user to trust the decisions of a group of people is to know that a group shares the same values and has incentives towards the success of the same project/product.</p>\n<p><strong>In fact, I believe that in general when these votes occur, the more unanimous the decisions are, the stronger the community is.</strong></p>\n<blockquote>\n<p><strong>NOTE:</strong> Although Web 3 communities are stronger than Web 2 ones, I believe that when something goes wrong the Web 3 communities break faster as they don’t have a common enemy due to the decentralized concept (e.g. LUNA debacle). On the other hand, Web 2 communities can “hold” onto the fact that their common enemy is now the entity that they trusted to act on their best interests (e.g. Robinhood vs wallstreetbets).</p>\n</blockquote>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"why-build-strong-communities\">Why build strong communities?<a href=\"https://didierlopes.com/blog/web3-symbols-and-community#why-build-strong-communities\" class=\"hash-link\" aria-label=\"Direct link to Why build strong communities?\" title=\"Direct link to Why build strong communities?\">​</a></h3>\n<p><em>The Web 3.0 concept doesn’t only benefit from strong communities but is built on top of it.</em> For worldwide adoption in products/projects/companies the space need strong communities.</p>\n<p>Why does money have value? Because people believe that they will be able to exchange it for goods/services in the future. Why do people believe that? Because they trust the entity that is managing such currency.</p>\n<p>Analogously, for a digital asset to have value, people need to believe that they will be able to exchange it for goods/services in the future. Since there is no entity to trust, people need to believe that the community will believe that a certain digital asset has value. This belief exists because there are incentives (usually financial or status) for its members.</p>\n<p>Once this happens we enter into the law of supply and demand where the value of digital asset goes up as there is either less supply or more demand.</p>\n<p>These communities can easily be found on CT or Discord/Telegram servers.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2022-06-28-web3-symbols-and-community_1-eeeced33bdb2bdb3425be7f831d7d6cb.webp\" width=\"1400\" height=\"836\" class=\"img_ev3q\"></p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"how-are-strong-communities-created\">How are strong communities created?<a href=\"https://didierlopes.com/blog/web3-symbols-and-community#how-are-strong-communities-created\" class=\"hash-link\" aria-label=\"Direct link to How are strong communities created?\" title=\"Direct link to How are strong communities created?\">​</a></h3>\n<p>If we learn from history, we see that the most loyal and bigger communities <strong>always recurred at symbology</strong> to achieve such, some examples: sports clubs, religion, countries, clans, societies, …</p>\n<p>The truth is that we humans constantly seek this sense of belonging (or are afraid of being alone). When we see multiple people on social media utilizing the same symbols to represent their beliefs, we want to be part of that group, of that community.</p>\n<p>This can be seen over and over again on Web3, particularly in CT:</p>\n<ul>\n<li>Changing the eyes’ color of your twitter’s pfp which represents being bullish on crypto (usually red for BTC and blue for ETH)</li>\n<li>Emojis after the username</li>\n<li>Utilizing the NFT you acquired from a collection that you believe in</li>\n<li>Adding a “.eth” at the end of the username</li>\n</ul>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2022-06-28-web3-symbols-and-community_2-e45bfcda2875fdbc27778685685c7c41.webp\" width=\"1400\" height=\"746\" class=\"img_ev3q\"></p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"why-does-this-matter\">Why does this matter?<a href=\"https://didierlopes.com/blog/web3-symbols-and-community#why-does-this-matter\" class=\"hash-link\" aria-label=\"Direct link to Why does this matter?\" title=\"Direct link to Why does this matter?\">​</a></h3>\n<p>Companies outside of the Web 3.0 space will start picking up on this to build stronger communities and have a stronger identity (e.g. Notion and their employees pfp on social media). This is even more relevant for open source companies (Web 2.5 if you will), which rely on their communities to build a successful company (e.g. Hugging Face 🤗 ).</p>\n<blockquote>\n<p><em>I believe that companies will start thinking about the emojis that their community can use while coming up with the name of the brand and logo.</em></p>\n</blockquote>\n<br>\n<p>As for OpenBB, we are a fintech open source company that focuses on providing better investment research for everyone, anywhere. The finance sector we are in is composed of multiple players that have been on the top of the industry for decades. We come in with a radical different approach, bottom-up.</p>\n<blockquote>\n<p><em>Being open source for us is not a choice but a need if we are to disrupt traditional investment research platforms with years of head start.</em></p>\n</blockquote>\n<br>\n<p>Once we knew that we wanted the logo to be extracted from the “BB”, it was immediate that the butterfly emoji (🦋) would be used. Furthermore, a butterfly is a metaphor for transformation, which in our context, represents OpenBB Terminal allowing each investor to evolve and finally fly (i.e. achieve financial freedom).</p>\n<p>In order for our users to start relating to the butterfly emoji (🦋) with our brand we have several cues:</p>\n<ul>\n<li>On the landing page</li>\n</ul>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2022-06-28-web3-symbols-and-community_3-a9442e1d9ee4b7dfb8cd631adb7aebe6.webp\" width=\"1400\" height=\"485\" class=\"img_ev3q\"></p>\n<ul>\n<li>Official social media channels</li>\n<li>Our team members use it in their socials</li>\n</ul>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2022-06-28-web3-symbols-and-community_4-485e524e7dda8d4bf55ad486782343c3.webp\" width=\"1400\" height=\"342\" class=\"img_ev3q\"></p>\n<ul>\n<li>On the OpenBB Terminal as the default flair,</li>\n</ul>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2022-06-28-web3-symbols-and-community_5-c02f336f62678dc964d70b195fef9444.webp\" width=\"1400\" height=\"187\" class=\"img_ev3q\"></p>\n<p>And even to replace the asterisk (*) when inserting the password to enter our OpenBB Bot platform, <strong>because details matter.</strong></p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2022-06-28-web3-symbols-and-community_6-d5655079a536b1d698360f184cd03cfb.webp\" width=\"1400\" height=\"809\" class=\"img_ev3q\"></p>\n<p>And that is what we are doing at OpenBB to build a stronger community? Do you have any other tips/tricks? Feel free to share them!</p>\n<p>Hope you enjoyed this post and as always, am looking to hear feedback!</p>\n<p><em>PS: I’d like to take this chance to say that our OpenBB Bot launch will occur in the coming weeks, you won’t have to wait much longer 🦋</em></p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/web3-symbols-and-community",
            "title": "Web3, symbols and community",
            "summary": "This blog post discusses the importance of strong communities in the Web 3.0 space, the role of decentralization, and how voting frameworks based on smart contracts can empower users.",
            "date_modified": "2022-06-28T00:00:00.000Z",
            "tags": [
                "web3",
                "community",
                "decentralization",
                "blockchain",
                "smart-contracts"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/remote-flexible-work-salary",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2022-05-03-remote-flexible-work-salary.webp\"></p>\n<br>\n<p>This blog post discusses the importance of remote and flexible work hours, and how it can significantly improve work-life balance and productivity.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>I was thinking about remote + flexible hours, and I don’t think I would ever work for a company without these. At least by choice 🙃</p>\n<p>I mean, who would tell Morty and Sum Sum that I wouldn’t be at home to play?</p>\n<p><strong>I’m a strong believer that work should wrap around your lifestyle and not vice-versa.</strong></p>\n<p>On average, a person works 40 hours a week and sleeps 8 hours a day. This means that out of 168h per week you have 72h for personal time. In terms of percentage we have: 24% for work, 33% for sleep, and 43% for personal time.</p>\n<p>So how come most people have almost 2x as much personal time compared to work time and they still feel like they are in this 9–5 rat race and their life revolves around work?</p>\n<p>Well, here’s the 4 scenarios as I see it…</p>\n<p><strong>1. The work is not remote (and not flexible).</strong></p>\n<ul>\n<li>If we account for the commute and stress associated with, personal time gets directly transferred into work time.</li>\n<li>E.g. with a daily 2 hour commute Mon-Fri, which is very typical, this means that your personal time is divided into 30% for work and 37% for personal. This isn’t event including the part where you have to prepare to leave the house, and the tiredness resultant from the commute.</li>\n</ul>\n<p><strong>2. The work is remote but not flexible.</strong></p>\n<ul>\n<li>This is much better than the previous. But it’s still not good enough. The argument here is not due to absolute time but performance and state of mind.</li>\n<li>Life is not straightforward. We, as individuals, are very different between ourselves. Our bodies, mind, brain, relationships, … work very differently. By not being flexible on the working hours you are basically ignoring all of that diversity and grouping everyone into a single 9–5 + Mon-Fri category.</li>\n<li><em>The “ironic” part is that most companies promote diversity and don’t think about this. Which just shows that the diversity topic has become very much a marketing vehicle.</em></li>\n<li>In my case, I’m a night owl, I don’t usually wake up too early, because I am much more productive when I stay awake until 3/4 am. If I have to wake up early because someone decided that 8:30am was the time that everyone needed to “check in” you are basically not getting the most out of me.</li>\n<li>One may wonder, well, this is a company problem because they are paying for an employee that is not performing as much as they could. Unfortunately, that’s not true, it’s a much bigger problem to the employee. This is because when an employee excels at a job they tend to have a much happier life which in turn increases performance, which increases happiness, and so on and so forth.</li>\n</ul>\n<p><strong>3. There is no mention for not remote but flexible because, in my opinion, that makes very little sense.</strong></p>\n<p><strong>4. Now, let’s imagine the scenario where the work is remote and flexible.</strong></p>\n<ul>\n<li>This is where it gets interesting. When we fall on this scenario your job perspective changes drastically. This is because at this point you put yourself first and can define your own priorities while having a pool of time to get a job done at your own time.</li>\n<li>E.g. you can plan activities with friends, do exercise, meditate, … whatever suits your lifestyle. Which will give you a boost of energy to perform even better at your job. On top of this, you don’t need to squash the work within Mon-Fri, once you are in this flexible regime you may use the weekend to your advantage. Flights at 20 Euros on Tuesday to come back Thursday? Fine, I’ll work during weekend to make up for this time</li>\n<li>There are people that love a 9–5 Mon-Fri schedule and that is fine. For those it means that the 9–5 Mon-Fri system implemented got it right. In fact, I would argue, that they are still wrapping work around lifestyle, it’s just that their lifestyle is working 9–5 Mon-Fri and enjoying time outside these hours.</li>\n</ul>\n<p>The downsides of this fully flexible work are:</p>\n<ul>\n<li>Interaction with coworkers and communication. But with us going global due to remote work, it doesn’t really matter, since the 9–5 hours of different countries would already lead to this problem</li>\n<li>Tracking employee timesheet. I think that a company shouldn’t track an employee timesheet because results are far more important than working hours, and can be just as measurable.</li>\n</ul>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>All of this to say that at OpenBB we have:</p>\n<ul>\n<li><strong>REMOTE WORK:</strong> As long as you are in a location with internet access, we are not worried. This allows us to build a strong diverse team with different backgrounds and ideas.</li>\n<li><strong>FLEXIBLE HOURS:</strong> We believe that your work should wrap around your lifestyle and not vice-versa. As long as you excel, you will not be asked why you woke up at noon.</li>\n<li><strong>UNLIMITED HOLIDAYS:</strong> Who has time to track holidays when building such an exciting project? We trust in our people to manage their own PTO and keep performing at the highest level.</li>\n</ul>\n<p>AND this is how I sleep at night having no idea at what time John logged in and out:</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2022-05-03-remote-flexible-work-salary_1-716587b9870487f701358f1249bfa820.webp\" width=\"732\" height=\"549\" class=\"img_ev3q\"></p>\n<p>Ohhh, and we’re hiring!</p>\n<p>If you provide a referral to someone that ends up joining OpenBB, I will transfer you $100 as a token of appreciation 🦋</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/remote-flexible-work-salary",
            "title": "Remote + Flexible work >> Salary",
            "summary": "This blog post discusses the importance of remote and flexible work hours, and how it can significantly improve work-life balance and productivity.",
            "date_modified": "2022-05-03T00:00:00.000Z",
            "tags": [
                "remote-work",
                "flexible-hours",
                "work-life-balance",
                "productivity"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/looking-for-a-new-tattoo-openbb-has-you-covered-literally",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2022-04-21-looking-for-a-new-tattoo-openbb-has-you-covered-literally.webp\"></p>\n<br>\n<p>Exploring unconventional ways to increase brand visibility, OpenBB's co-founder gets a tattoo of the company logo. This blog post discusses the thought process behind this unique marketing strategy.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>When <a href=\"https://github.com/OpenBB-finance/OpenBBTerminal\" target=\"_blank\" rel=\"noopener noreferrer\">OpenBB Terminal</a> started last year, I went from having your typical career as a Software Engineer to becoming a co-founder &amp; CEO of a C-Corporation overnight. One thing that I've really learnt from this change, is I can no longer code for 12–16 hours a day straight as my role now involves so much more than this… and most interestingly, one of those things is marketing.</p>\n<p>During Easter in Lisbon, I was thinking about how to increase the visability of <a href=\"https://openbb.co/\" target=\"_blank\" rel=\"noopener noreferrer\">OpenBB</a>. <em>An investment research platform for everyone, anywhere</em>. Seems self-explanatory and something most of us would relate to, but the problem is reaching a bigger audience.</p>\n<p>Due to <a href=\"https://openbb.co/blog/gme-didnt-take-me-to-the-moon-but-gamestonk-terminal-did\" target=\"_blank\" rel=\"noopener noreferrer\">our $8.5M funding</a> we have money in the bank, which means we can afford to do some ads campaigns. However, I very much dislike the traditional type of ads, whether that is with Google, Instagram, Twitter or YouTube. Particularly YouTube ones, when I see an ad there I immediately think less of the product being advertised due to how intrusive these are.</p>\n<p>That's why I started thinking of ways to share our OpenBB brand in a non-intrusive way. In fact, I went one step further and started thinking when I personally would welcome ads.</p>\n<p>Funnily enough, the first thing that came to my mind was when I go to the bathroom without my phone. Although there's no ads on the back of shampoos/shower gel/soap/spray, I would very much welcome them.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2022-04-21-looking-for-a-new-tattoo-openbb-has-you-covered-literally_1-09619c2356b5597dbb72145a6746584c.webp\" width=\"511\" height=\"508\" class=\"img_ev3q\"></p>\n<p>It's not like knowing the %s of ingredients that makes up cleaning products has a lot of use cases…</p>\n<p>This brought me to the conclusion that I would only welcome ads if I was bored and didn't have anything keeping me \"too busy\". This immediately made me think of London underground ads (the most effective type of DOOH imho). I always read those ads. The main reason being that I don't have WiFi underground and the noise is too loud to listen to a podcast. Hence, I imagined the underground looking like:</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2022-04-21-looking-for-a-new-tattoo-openbb-has-you-covered-literally_2-8b939e03755c25ea2e38272c0e381fcc.webp\" width=\"1400\" height=\"1077\" class=\"img_ev3q\"></p>\n<p>When I checked for the prices, I was looking at a marketing campaign for a couple of days in a couple of stations costing over 5 digits, which is quite expensive for the short time-span.</p>\n<p>Therefore, I started to think of cheaper alternatives that yielded a better ROI. The next thing that passed through my mind was wearing OpenBB swag (yet to be revealed, <a href=\"https://openbb.co/newsletter\" target=\"_blank\" rel=\"noopener noreferrer\">subscribe to our newsletter</a> to know more). However, I feel like nowadays everyone has a t-shirt with a different logo and these aren't as noticeable as before — at least that's my perspective.</p>\n<p>This lead me to think: <strong>What about a tattoo?</strong> It's a similar concept than OpenBB clothes but more powerful. In addition, when wearing OpenBB clothes with a visible tattoo, this will create a \"curiosity\" effect since the symbol is repeated (clothes and tattoo). In addition, I've not come across anyone using their body to express their brand.</p>\n<p>Later that day I booked a tattoo slot, paid 100 euros, and got the OpenBB logo on the back of my arm as shown below,</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2022-04-21-looking-for-a-new-tattoo-openbb-has-you-covered-literally_3-db376a320623ea5f1bb45b968c33d517.webp\" width=\"1122\" height=\"1496\" class=\"img_ev3q\"></p>\n<p>I will let you know on my socials how many people ask about this tattoo over the course of my life.</p>\n<p>And if you like <a href=\"https://www.openbb.design/9242dc28c/p/809a44-logo\" target=\"_blank\" rel=\"noopener noreferrer\">our logo</a> and <a href=\"https://www.openbb.design/9242dc28c/p/91bbcc-our-values\" target=\"_blank\" rel=\"noopener noreferrer\">our values</a>, OpenBB will pay you for the tattoo.</p>\n<p><strong>One things for sure, now I can definitely put the gym membership as a company expense since I'm a walking billboard 😄</strong></p>\n<p>The first walking/running/coding/eating/drinking OpenBB billboard.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/looking-for-a-new-tattoo-openbb-has-you-covered-literally",
            "title": "Looking for a new tattoo? OpenBB has you covered… literally.",
            "summary": "Exploring unconventional ways to increase brand visibility, OpenBB's co-founder gets a tattoo of the company logo. This blog post discusses the thought process behind this unique marketing strategy.",
            "date_modified": "2022-04-21T00:00:00.000Z",
            "tags": [
                "openbb",
                "marketing",
                "branding",
                "brand-awareness",
                "tattoo",
                "guerilla-marketing",
                "startup-culture",
                "founder-story"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/how-i-created-the-best-discord-meme-bot",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2022-04-09-how-i-created-the-best-discord-meme-bot.webp\"></p>\n<br>\n<p>In this blog post, I share my journey of creating a Discord meme bot, the role it played in building a vibrant community around our open source project, and how you can add your own memes to the bot.</p>\n<p>The open source code is available <a href=\"https://github.com/DidierRLopes/discord-memes\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"background\">Background<a href=\"https://didierlopes.com/blog/how-i-created-the-best-discord-meme-bot#background\" class=\"hash-link\" aria-label=\"Direct link to Background\" title=\"Direct link to Background\">​</a></h2>\n<p>Over the past few weeks, life has been very chaotic on my end, mostly due to the announcement of <a href=\"http://www.openbb.co/\" target=\"_blank\" rel=\"noopener noreferrer\">OpenBB</a> last week which you can read the full story on <a href=\"https://openbb.co/blog/gme-didnt-take-me-to-the-moon-but-gamestonk-terminal-did\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<p>When I started <a href=\"https://github.com/OpenBB-finance/OpenBBTerminal\" target=\"_blank\" rel=\"noopener noreferrer\">OpenBB Terminal</a>, all my focus was on building, building and building. Once I made the project open source and contributors started to appear, I slowly saw my time shifting <strong>from building a product to building a community</strong>. This community ultimately would end up building the product, but from my end, I need to be able to pass on my passion to the project and vision.</p>\n<p>Developing features for the terminal only took me a couple of minutes, whereas the connection with the community is a long-time game. You don’t become close with someone you’ve never met within couple of minutes. Instead you need to put effort into the relationship and <strong>consistency is key</strong>.</p>\n<p>The community on our Discord was growing day by day. And so was my relationship with the people in it. The truth is, we were not only sharing insights about the platform, but were laughing and bonding together whilst building it. <strong>And memes/gifs are a big part of these interactions.</strong></p>\n<p>For people who know me, they know how much I love memes and how I can always create memes for every situation (honestly, all the time I spent on Instagram is finally paying off).</p>\n<p>Although I believe that we have one of the most exciting open source projects going on, I also strongly believe that our fun culture (i.e. memes) is what makes contributors want to work in this particualr environment. <strong>Building the future of investment research can be fun and this is what we’re proving.</strong></p>\n<p>At this stage, I think I’ve spent more time interacting with people than I have working on the platform. The funny thing is that <strong>the platform is 10x better than what it would be if I was working on my own</strong>. Creating a strong community pays off and this is why since the start I was having calls with literally everyone to help them install our platform. Today, most of the team at OpenBB was met on Discord whilst working on the platform. <strong>I didn’t need any interviews, they weren’t candidates anymore but people that I enjoyed to work with</strong> and wanted on the team.</p>\n<p>Sorry for the background story, but it was important to me to explain why I worked on this. <strong>The interesting part of the article starts now.</strong></p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"development\">Development<a href=\"https://didierlopes.com/blog/how-i-created-the-best-discord-meme-bot#development\" class=\"hash-link\" aria-label=\"Direct link to Development\" title=\"Direct link to Development\">​</a></h2>\n<p><strong>The idea of Discord Memes is to avoid to open <a href=\"https://imgflip.com/\" target=\"_blank\" rel=\"noopener noreferrer\">imgflip</a> everytime I wanted to add text to a meme.</strong> Personally, I love the gifs available through Discord but I think a meme with text is much more powerful (and funny).</p>\n<p>When I started coding this here and there, I wanted the code to be super straightforward so it was very simple and fast to add a new meme to the pool. And so I did.</p>\n<p>The process to add new memes is incredibly easy. Go to the <a href=\"https://github.com/DidierRLopes/discord-memes\" target=\"_blank\" rel=\"noopener noreferrer\">project</a> and star it for starters (also <a href=\"https://github.com/OpenBB-finance/OpenBBTerminal\" target=\"_blank\" rel=\"noopener noreferrer\">OpenBB Terminal</a> since you’re at it). Then,</p>\n<ol>\n<li>\n<p>Add the meme you want to the <code>memes/</code> folder, e.g. <code>spongebob.webp</code></p>\n</li>\n<li>\n<p>Then create a function with the same name of the image (e.g. <code>spongebob</code>) with the following format</p>\n</li>\n</ol>\n<br>\n<div class=\"language-python codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-python codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token decorator annotation punctuation\" style=\"color:rgb(248, 248, 242)\">@create_and_send_meme</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">def</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(80, 250, 123)\">spongebob</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token plain\">inter</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> text</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"> </span><span class=\"token builtin\" style=\"color:rgb(189, 147, 249)\">str</span><span class=\"token plain\"> </span><span class=\"token operator\">=</span><span class=\"token plain\"> </span><span class=\"token boolean\">None</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> _</span><span class=\"token operator\">=</span><span class=\"token boolean\">None</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    </span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">if</span><span class=\"token plain\"> text</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">:</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">        _</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">text</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">            </span><span class=\"token number\">0.5</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">            </span><span class=\"token number\">0.2</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">            </span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"\\n\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">join</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token plain\">wrap</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">''</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">join</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token plain\">choice</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token builtin\" style=\"color:rgb(189, 147, 249)\">str</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">upper</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> </span><span class=\"token builtin\" style=\"color:rgb(189, 147, 249)\">str</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">lower</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token plain\">c</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">for</span><span class=\"token plain\"> c </span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">in</span><span class=\"token plain\"> text</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> </span><span class=\"token number\">40</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">            fontsize</span><span class=\"token operator\">=</span><span class=\"token number\">20</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">            color</span><span class=\"token operator\">=</span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"white\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">            alpha</span><span class=\"token operator\">=</span><span class=\"token number\">0.9</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">            horizontalalignment</span><span class=\"token operator\">=</span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"center\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">            path_effects</span><span class=\"token operator\">=</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">[</span><span class=\"token plain\">pe</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">withStroke</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token plain\">linewidth</span><span class=\"token operator\">=</span><span class=\"token number\">4</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> foreground</span><span class=\"token operator\">=</span><span class=\"token string\" style=\"color:rgb(255, 121, 198)\">\"black\"</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">]</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">        </span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">    </span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">return</span><span class=\"token plain\"> _</span><br></span></code></pre></div></div>\n<ol start=\"3\">\n<li>That’s it.</li>\n</ol>\n<br>\n<p><strong>Note:</strong> I created a python decorator <code>@create_and_send_meme()</code> that basically abstracts all the memes created and picks up the image on memes with the same name of the function. This way, the person adding a meme just needs to focus on the text on the image, i.e. it's location, size, where it wraps, colours and alignment.</p>\n<p>I used a playground.ipynb notebook, which is also on the repo, to increase the speed of the text placement on each of the memes I added.</p>\n<p>This is how it looks,</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2022-04-09-how-i-created-the-best-discord-meme-bot_1-689c4430503cb2d25e2cb54daa7b4a1c.webp\" width=\"1048\" height=\"1622\" class=\"img_ev3q\"></p>\n<p>OR</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2022-04-09-how-i-created-the-best-discord-meme-bot_2-19ea92238ec06d3d24d6ff0406703b30.webp\" width=\"1080\" height=\"816\" class=\"img_ev3q\"></p>\n<p>As you can see, our Discord server just stepped up. <a href=\"https://openbb.co/discord\" target=\"_blank\" rel=\"noopener noreferrer\">Join us</a> to try out the meme bot, build the future of investment research or just to say hi.</p>\n<p>We’ll be waiting for you. 🦋</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/how-i-created-the-best-discord-meme-bot",
            "title": "How I created the best discord meme bot",
            "summary": "In this blog post, I share my journey of creating a Discord meme bot, the role it played in building a vibrant community around our open source project, and how you can add your own memes to the bot.",
            "date_modified": "2022-04-09T00:00:00.000Z",
            "tags": [
                "discord",
                "meme-bot",
                "open-source",
                "community-building"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/meet-the-most-advanced-investment-research-platform",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2022-03-21-meet-the-most-advanced-investment-research-platform.webp\"></p>\n<br>\n<p>Meet the most advanced investment research platform. This blog post introduces Gamestonk Terminal, an advanced investment research platform, and discusses its features and automation capabilities.</p>\n<p>The open source code is available <a href=\"https://github.com/DidierRLopes/GamestonkTerminal\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>Several people have asked me why <a href=\"https://github.com/GamestonkTerminal/GamestonkTerminal\" target=\"_blank\" rel=\"noopener noreferrer\">Gamestonk Terminal</a> doesn’t have release versions, and the main reason is because at the pace the team codes and the rate that new features / bug fixes appear it doesn’t yet makes sense to do so.</p>\n<p>To give you an example, recently I shared the first <strong>DEMO of what the terminal can do</strong>, and I mention about our “routines” automation concept.</p>\n<div class=\"flex place-items-center justify-center items-center rounded-sm mx-auto\"><iframe src=\"https://www.youtube.com/embed/fqGPK8OVHLk?si=Xu7rtb-0iHmTDdjj\" width=\"800\" height=\"400\"></iframe></div>\n<br>\n<p>One week later, using the latest version of the terminal, on top of that simplistic routine type you are able to:</p>\n<ol>\n<li>Provide variable input variables when calling the routine using $ARGV[i] (I used Perl convention here eheh)</li>\n<li>Execute routines from within the terminal directly</li>\n<li>Add comments to the routines so the process is more clear</li>\n<li>Exporting data to a folder of choice is now possible</li>\n<li>Exporting a file with a pre-defined name is now possible</li>\n<li>Allow for the first line of the routines to be selecting a folder to export ALL the data</li>\n</ol>\n<br>\n<p>See below a 1 minute video of what these routine automated scripts look like!</p>\n<div class=\"flex place-items-center justify-center items-center rounded-sm mx-auto\"><iframe src=\"https://www.youtube.com/embed/pH0srojpv8Q?si=778fQVB-YqNdxDL3\" width=\"800\" height=\"400\"></iframe></div>\n<br>\n<p>Reach out if you have any question to the team, there’s very little we can’t do!</p>\n<p>This is the way!</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/meet-the-most-advanced-investment-research-platform",
            "title": "Meet the most advanced investment research platform",
            "summary": "Meet the most advanced investment research platform. This blog post introduces Gamestonk Terminal, an advanced investment research platform, and discusses its features and automation capabilities.",
            "date_modified": "2022-03-21T00:00:00.000Z",
            "tags": [
                "investment-research",
                "gamestonk-terminal",
                "automation",
                "routines"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/gamestonk-terminal-ux-features",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2022-01-06-gamestonk-terminal-ux-features.webp\"></p>\n<br>\n<p>Gamestonk Terminal's UX/UI features and the teamwork behind their implementation.</p>\n<p>The open source code is available <a href=\"https://github.com/DidierRLopes/GamestonkTerminal\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p><strong>Features attract users, UX/UI conquers them ⚔️</strong></p>\n<p>Throughout month of December, me and 3 of the most active maintainers of <a href=\"https://github.com/GamestonkTerminal/GamestonkTerminal\" target=\"_blank\" rel=\"noopener noreferrer\">Gamestonk Terminal</a> had a meeting where we discussed shifting our focus from adding features, to improving the terminal UX/UI to make it even more attractive. The main outcomes of these meeting were:</p>\n<ol>\n<li>\n<p>Relative and Absolute menu jumping, e.g. if i’m in crypto/ta and want to go to stocks/ta I can do:</p>\n<p>a. Absolute: <code>/stocks/load tsla/ta</code></p>\n<p>b. Relative: <code>../../stocks/load tsla/ta</code></p>\n</li>\n<li>\n<p>Scripting feature. You can now interact with the terminal through a sequence of commands, e.g.: <code>stocks/disc/ugs -l 3/gtech/active</code>.</p>\n</li>\n<li>\n<p><code>reset</code> command everywhere to allow for faster development as it exits from the terminal and comes to the same menu running new terminal code and its API keys.</p>\n</li>\n<li>\n<p>Auto-completion in commands with choices.</p>\n</li>\n<li>\n<p>When misspelling a command name, if it’s similar enough that the terminal recognises the right command, it will replace it, to speed up interaction.</p>\n</li>\n</ol>\n<br>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2022-01-06-gamestonk-terminal-ux-features_1-c60b8661301b124c409000bc2b879afc.webp\" width=\"2000\" height=\"1250\" class=\"img_ev3q\"></p>\n<ol start=\"6\">\n<li>Running a <code>.gst</code> job, like <code>python terminal.py scripts/test_stocks_disc.gst</code> which allows to run a sequence of commands of the terminal. In the future we can take advantage of this for integration tests. The user can build their own daily routines to speed up the investment process.</li>\n</ol>\n<br>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2022-01-06-gamestonk-terminal-ux-features_2-b2b8c0f0ec856a5814a06387b3ae28b0.webp\" width=\"2000\" height=\"1010\" class=\"img_ev3q\"></p>\n<p>Now, I know what you’re thinking. This is a massive improvement over the terminal usage up until now, and that’s a <strong>LOT</strong> of code changes. Which is very much true, to be specific, this engineering effort resulted in:</p>\n<blockquote>\n<p><strong>370 files changed with 44,875 additions and 18,463 deletions</strong></p>\n</blockquote>\n<br>\n<p>And you may be wondering how long did this take us to do. Nope, it wasn’t months but…</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2022-01-06-gamestonk-terminal-ux-features_3-2e729c55cbcef8dd5a42ac137adfd958.webp\" width=\"422\" height=\"233\" class=\"img_ev3q\"></p>\n<p><strong>1 week. Yup, a single f*king week.</strong> You can see that it was finalised with these PRs (<a href=\"https://github.com/GamestonkTerminal/GamestonkTerminal/pull/1049\" target=\"_blank\" rel=\"noopener noreferrer\">#1049</a>, <a href=\"https://github.com/GamestonkTerminal/GamestonkTerminal/pull/1041\" target=\"_blank\" rel=\"noopener noreferrer\">#1041</a>, <a href=\"https://medium.com/@dro-lopes/gamestonk-terminal-ux-features-f9754b484919#1048\" target=\"_blank\" rel=\"noopener noreferrer\">#1048</a>).</p>\n<p>In that week we split work, did pair programming, we called each other to discuss better implementation practices, we changed the architecture 2/3 more times… On top of that, I was feeling overwhelmed with the stocks menu, I clearly underestimated how many features we have (how naive…), so the 3 other maintainers jumped on it and helped me out. In 3 or so years of software engineering, this was** teamwork like I’ve not felt before**.</p>\n<p>That weekend I was so happy as we accomplished this task that I think I didn’t even work on the terminal that Sunday! Doesn’t happen often these days!</p>\n<p>However, as a good friend of mine told me:</p>\n<blockquote>\n<p><em><strong>“The entertainment industry hasn’t found yet something more appealing than developing code towards a product I believe in and with people I like”</strong></em></p>\n</blockquote>\n<br>\n<p>I still think about this often, and this is what I tell my girlfriend, to explain why I’m coding and not playing Mario Kart 8 Deluxe with her. (the fact she always beats me at it also may be considered as a factor 🤣).</p>\n<p>You may be thinking this is a one off, the reality is that <strong>it isn’t</strong>. Another example can be seen in <a href=\"https://dev.to/northern64bit/aspiring-16-year-old-quant-developer-contributing-to-open-source-application-16k4\" target=\"_blank\" rel=\"noopener noreferrer\">this blog post</a>. This goes over the story of the development of our discord bot where it all started from a message from a <strong>16yo contributor that wants to become a quant</strong>. He wanted to not only improve his python skills with us but also bring the terminal features to a bigger audience. Working with us in an open-source project is helping him towards achieving his life-goal dream.</p>\n<p>While I write this post another contributor, finishing his CPA, is working on <a href=\"https://github.com/OpenBB-finance/OpenBBTerminal/pull/1141\" target=\"_blank\" rel=\"noopener noreferrer\">improving the code resulting from that UX effort by creating a base class</a> so that new developers can add controllers much easily (he estimates a reduction of 11% of codebase size based on “napkin maths” as he puts it).</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2022-01-06-gamestonk-terminal-ux-features_4-5cb20e864126924eea8e774a9d93e6f1.webp\" width=\"970\" height=\"542\" class=\"img_ev3q\"></p>\n<p>While user experience is critical, so is user interface. And that is why our next engineering effort will be around it. We already have something in the works in <a href=\"https://github.com/GamestonkTerminal/GamestonkTerminal/pull/1140\" target=\"_blank\" rel=\"noopener noreferrer\">this PR</a>, where we can draw lines and write text! Almost like TradingView (almost… 😬).</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2022-01-06-gamestonk-terminal-ux-features_5-c74830909c633ea3944eca192f83b8dc.webp\" width=\"3404\" height=\"1412\" class=\"img_ev3q\"></p>\n<p>So, keep on the lookout because 2022 is gonna be a big year for us!! 🦋 🚀</p>\n<p>Ohh, before I say thanks for the read and all that, it’s also worth mentioning that there’s a PR in the queue for a new context called “<strong>alternative data</strong>”, which already has a <strong>COVID menu</strong> to factor that data into account on your investments.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2022-01-06-gamestonk-terminal-ux-features_6-57aa665956f2b38640f01c4c6eae552a.webp\" width=\"2000\" height=\"886\" class=\"img_ev3q\"></p>\n<p><em>PS: The blue text is because we are transitioning towards <a href=\"https://github.com/Textualize/rich\" target=\"_blank\" rel=\"noopener noreferrer\">rich package</a> which gives a lot more freedom when it comes to improving our user interface.</em></p>\n<br>\n<p>Thanks for your read, and if you enjoy Gamestonk Terminal, please reach out to <a href=\"https://discord.gg/ptYabd8w\" target=\"_blank\" rel=\"noopener noreferrer\">our discord</a> to say thank you, or ideally: for <strong>@terp340</strong> to change date format to dd/MM/YYYY — <strong>the only correct one</strong>!</p>\n<p>Happy 2022 with lots of love ❤️</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/gamestonk-terminal-ux-features",
            "title": "UX/UI is better than features",
            "summary": "Gamestonk Terminal's UX/UI features and the teamwork behind their implementation.",
            "date_modified": "2022-01-06T00:00:00.000Z",
            "tags": [
                "gamestonk-terminal",
                "ux/ui",
                "software-development",
                "teamwork"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/sector-and-industry-analysis-gamestonk-terminal",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2021-12-02-sector-and-industry-analysis-gamestonk-terminal.webp\"></p>\n<br>\n<p>The development journey of a new Sector and Industry Analysis feature for Gamestonk Terminal, integrating the FinanceDatabase package.</p>\n<p>The open source code is available <a href=\"https://github.com/DidierRLopes/GamestonkTerminal\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>The end-to-end story of developing a new <strong>Sector and Industry Analysis</strong> for <a href=\"https://github.com/GamestonkTerminal/GamestonkTerminal\" target=\"_blank\" rel=\"noopener noreferrer\">Gamestonk Terminal</a> from scratch.</p>\n<p>On the 13th of October, <a href=\"https://github.com/JerBouma\" target=\"_blank\" rel=\"noopener noreferrer\">Jeroen Bouma</a> (a ALM advisor and python enthusiast) reached out in order to integrate his <a href=\"https://github.com/JerBouma/FinanceDatabase\" target=\"_blank\" rel=\"noopener noreferrer\">FinanceDatabase package</a> into <a href=\"https://github.com/GamestonkTerminal/GamestonkTerminal\" target=\"_blank\" rel=\"noopener noreferrer\">Gamestonk Terminal</a>.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2021-12-02-sector-and-industry-analysis-gamestonk-terminal_1-332e91061348a870bd80b17e4aff88f7.webp\" width=\"1400\" height=\"709\" class=\"img_ev3q\"></p>\n<p>After having a call with Jeroen to bounce ideas, it was clear that our terminal needed such capability to be even more powerful (as if <strong>over 500 features</strong> already and counting didn’t already do the trick eheh). However, at the time I was too busy to work on the concept so I asked Jeroen if he could sketch something up on a jupyter notebook.</p>\n<p>Within the following week, Jeroen sent a Jupyter notebook explaining the FinanceDatabase module and what we could have in a Sector and Industry analysis.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2021-12-02-sector-and-industry-analysis-gamestonk-terminal_2-9c90c41640cfce3bae055a0726c23db3.webp\" width=\"1400\" height=\"617\" class=\"img_ev3q\"></p>\n<p>In addition, he also mentioned his <a href=\"https://github.com/JerBouma/ThePassiveInvestor\" target=\"_blank\" rel=\"noopener noreferrer\">PassiveInvestor package</a>, and ended up <a href=\"https://github.com/GamestonkTerminal/GamestonkTerminal/pull/857\" target=\"_blank\" rel=\"noopener noreferrer\">implementing it on his own in Gamestonk Terminal</a>! This was a great addition, as it strengthened our <strong>ETF context</strong> and provided a slick Excel report for the Excel fans out there! See his <a href=\"https://www.linkedin.com/feed/update/urn:li:activity:6859887432532291584/\" target=\"_blank\" rel=\"noopener noreferrer\">LinkedIn post</a> on the experience.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2021-12-02-sector-and-industry-analysis-gamestonk-terminal_3-bd2293dbaad8584e6f1bc2c9f2a8a828.webp\" width=\"1400\" height=\"707\" class=\"img_ev3q\"></p>\n<p>...</p>\n<p>Forward to last weekend (1.5 months later), I had a free Sunday afternoon so started working on the development of this menu. I started by thinking about what would make this menu more flexible and powerful.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2021-12-02-sector-and-industry-analysis-gamestonk-terminal_4-c85ab53ce4834da320b1427375fca2d6.webp\" width=\"1400\" height=\"916\" class=\"img_ev3q\"></p>\n<p>These were my thoughts about what it needs:</p>\n<ul>\n<li><strong>Several filtering parameters</strong> as the number of companies in the database is pretty huge with 155.705 tickers, 16 sectors, 242 industries, 111 countries and 82 exchanges. These were the filters selected: Country, Sector, Industry, Market Cap and Flag to include/exclude international exchanges.</li>\n<li><strong>To be able to do some statistics on the sector</strong>, industries and countries (e.g. companies per sector/industry with a specified country and market cap) which allows users to better understand companies landscape of a sector and industry.</li>\n<li><strong>To get the financials of the companies that fall under that filter subset</strong> (e.g. return on assets, quick ratio, debt to equity), and then compare these in order to get the best performers.</li>\n<li>Since one of the previous financials isn’t enough to understand which company would be best to invest in, I wanted the filtered companies to have the capability to jump onto the comparison analysis menu so you could get all the capabilities of comparing historical price data, volume data, income/balance/cash flow, sentiment, or even technical indicators.</li>\n<li>If in the stocks context I had Tesla loaded, I wanted to go into this sia menu and get all the filtering parameters to be ready to filter for companies similar to Tesla in terms of (Sector, Industry, Country and Market Cap).</li>\n</ul>\n<p>By Sunday night, I created the <a href=\"https://github.com/GamestonkTerminal/GamestonkTerminal/pull/995\" target=\"_blank\" rel=\"noopener noreferrer\">pull request for this</a>. Due to the due diligent reviews performed by the main contributors of the project, the menu got a lot of improvements. Some of them were:</p>\n<ul>\n<li>Do not display companies that account for under a certain threshold (1%) and therefore sum them in an “Others” slice.</li>\n<li>Allow to export all the data as a table.</li>\n<li>After filtering and getting financials, save the data for faster data retrieval if the same filters are used.</li>\n<li>Minor bug fixes.</li>\n</ul>\n<p>After a lot of comments and feedback from the main maintainers, and everyone being happy with this first iteration, the PR got merged. In fact, one of the main maintainers found a hidden gem while testing it.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2021-12-02-sector-and-industry-analysis-gamestonk-terminal_5-dbc60d951c9a563208400e3c43825941.webp\" width=\"1400\" height=\"78\" class=\"img_ev3q\"></p>\n<p>In the meantime, I’ve been in contact with Jeroen about adding some more capabilities to his FinanceDatabase package so that everyone could benefit from them. Some examples are:</p>\n<ul>\n<li>When an industry is selected, the corresponding sector should be automatically filled.</li>\n<li>If I select a country and a market cap for filtering, my sector choices should be bounded by what exists within those.</li>\n<li>I should be able to query about companies landscape in terms of a country. E.g. I want to understand what countries have the most large cap companies within the Financial Services sector.</li>\n</ul>\n<p>This would not only make the FinanceDatabase a more powerful Package, which would in turn benefit Gamestonk Terminal sia menu, and ultimately our thousands of users!</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2021-12-02-sector-and-industry-analysis-gamestonk-terminal_6-076f6f0b288cd5798d0a3e8858bfad63.webp\" width=\"768\" height=\"447\" class=\"img_ev3q\"></p>\n<p>This is an example of how the Sector and Industry Analysis menu looks (as a bonus I show how you can go into the Comparison Analysis menu):</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2021-12-02-sector-and-industry-analysis-gamestonk-terminal_7-6fb6fe69a382ae184b75209c34345c0d.webp\" width=\"2560\" height=\"928\" class=\"img_ev3q\"></p>\n<p>Next time you know, it all starts with an e-mail. At Gamestonk Terminal we are on a role to have the best investment research terminal, and hope this story reflects it.</p>\n<p>Try it now, it’s free. ❤️</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/sector-and-industry-analysis-gamestonk-terminal",
            "title": "Sector and Industry Analysis — Gamestonk Terminal",
            "summary": "The development journey of a new Sector and Industry Analysis feature for Gamestonk Terminal, integrating the FinanceDatabase package.",
            "date_modified": "2021-12-02T00:00:00.000Z",
            "tags": [
                "gamestonk-terminal",
                "sector-analysis",
                "industry-analysis",
                "financedatabase",
                "open-source"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/handing-your-twitter-account-to-your-most-avid-community-member",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2021-11-17-handing-your-twitter-account-to-your-most-avid-community-member.webp\"></p>\n<br>\n<p>Handing over the Twitter account of Gamestonk Terminal to an active community member and the impact it had on the project's growth and engagement.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>When I started <a href=\"https://github.com/GamestonkTerminal/GamestonkTerminal\" target=\"_blank\" rel=\"noopener noreferrer\">Gamestonk Terminal</a> I had no idea of the reach and impact it would have. From getting <strong>over 3.5k stars on GitHub on the first single day alone</strong>, to trending <a href=\"https://www.reddit.com/r/algotrading/comments/lrndzi/cant_afford_the_bloomberg_terminal_no_worries_i/\" target=\"_blank\" rel=\"noopener noreferrer\">on Reddit</a> and receiving overwhelming feedback, to receiving a message from an ex-colleague based in Switzerland about my name being <a href=\"https://news.ycombinator.com/item?id=26258773\" target=\"_blank\" rel=\"noopener noreferrer\">top 1 on Hackernews</a>. As if this wasn’t enough, a couple of days later the project got featured by <a href=\"https://www.vice.com/en/article/qjp9vp/gamestonk-terminal-is-a-diy-meme-stock-version-of-bloomberg-terminal\" target=\"_blank\" rel=\"noopener noreferrer\">VICE Magazine</a> and <a href=\"https://dailyfintech.com/2021/02/25/never-underestimate-bloomberg-but-here-are-5-reasons-why-the-gamestonk-terminal-is-a-contender/\" target=\"_blank\" rel=\"noopener noreferrer\">Daily Fintech</a>.</p>\n<p>As a result, my social life was impacted and had little time to even cuddle my puppy, due to the amount of feature requests, issues… the usual somehow ungrateful life of an open-source maintainer… I’m not complaining though, as I live for this.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2021-11-17-handing-your-twitter-account-to-your-most-avid-community-member_1-71da8bc1f90abad6582f3512499da7ca.webp\" width=\"1242\" height=\"1449\" class=\"img_ev3q\"></p>\n<p>Moving forward a couple of weeks, it became clear to myself that I was building a strong community around what can/will/should be a leading product in the emerging fintech industry and Internet 3.0. Therefore, I knew that github issues and discussions wouldn’t be enough to interact with all members of the community, so Discord turned out to be the best option going forward (let’s be honest: mostly because of the convenience that Discord offers to share memes, feel free to check my creations on <a href=\"https://discord.gg/2KnVnkDTxM\" target=\"_blank\" rel=\"noopener noreferrer\">our Discord</a>, you can thank me later).</p>\n<p>My next rookie mistake was thinking I could use Discord announcements and @ everyone, as a means for updating the community on new features. Being the #1 investment research free and open-source project on github gets you several PRs a day being merged, so in all the fairness the announcements were recurrent with constant several new features. You can check my <a href=\"https://www.youtube.com/watch?v=9BMI9cleTTg\" target=\"_blank\" rel=\"noopener noreferrer\">one hour live programming stream</a> of adding a feature to the terminal.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2021-11-17-handing-your-twitter-account-to-your-most-avid-community-member_2-8ca2fc6b6d42b316e99762e15bd85cb2.webp\" width=\"833\" height=\"500\" class=\"img_ev3q\"></p>\n<p>This is when I realized that Discord wasn’t the best place for this type of communication. I needed a platform where I could share these features ad-hoc and that only alerted users who wanted to be up-to-date with our latest features. And this is when I created our <a href=\"https://twitter.com/gamestonkt\" target=\"_blank\" rel=\"noopener noreferrer\">Twitter account</a>, @gamestonkt.</p>\n<p>Reviewing the history of our Twitter feed, you can see that this is exclusively what our handle was used for. It just shared new features every day. It felt like I was always playing catchup to the growing number of features piling up in the queue waiting to be announced on Twitter. With the project already having <strong>over 500 features</strong> in less 1 year, this inevitable outcome would be a surprise to no one. (<strong>yup, I repeat, over 500</strong>).</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2021-11-17-handing-your-twitter-account-to-your-most-avid-community-member_3-7f654efecb7e2620d21a8b76e87db084.webp\" width=\"1188\" height=\"1606\" class=\"img_ev3q\"></p>\n<p>However, I felt like <strong>it missed personality</strong>... With time being a limiting factor — time was more efficiently used improving the terminal — the public facing demonstrations were a lower priority. When you believe this much in a product, the product ends up speaking for itself.</p>\n<blockquote>\n<p><em>“If you build it, they will come” — Field of Dreams</em></p>\n</blockquote>\n<br>\n<p>It then occurred to me, why am I handling our Twitter? Why not leave this up to one of our most avid and vocal users that has been with project since beginning?</p>\n<p>As Jim from “The Office” would do, let’s do a PROS &amp; CONS table.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"pros\">Pros<a href=\"https://didierlopes.com/blog/handing-your-twitter-account-to-your-most-avid-community-member#pros\" class=\"hash-link\" aria-label=\"Direct link to Pros\" title=\"Direct link to Pros\">​</a></h3>\n<ul>\n<li>The user represents the community that the twitter content is targeted at.</li>\n<li>The user is an active daily user and will help to demonstrate features in the terminal.</li>\n<li>The user is keen on learning the ins and outs of the product.</li>\n<li>This user is not only a user anymore but a friend given his interaction with the maintainers.</li>\n<li>Lastly, I get to spend time doing what I enjoy: coding and meme content on our Discord.</li>\n</ul>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"cons\">Cons<a href=\"https://didierlopes.com/blog/handing-your-twitter-account-to-your-most-avid-community-member#cons\" class=\"hash-link\" aria-label=\"Direct link to Cons\" title=\"Direct link to Cons\">​</a></h3>\n<ul>\n<li>The user finds out my mother’s maiden name and the name of my first pet.</li>\n</ul>\n<p>This is really a no brainer the more you think about it. I think it depends a lot on the type of people you have in your community and how confident you are on this individual .</p>\n<p>We were lucky, because we had the <strong>perfect fit</strong>: an active Discord user <strong>@Danglewood</strong>, who had built an engaged audience, generating over 130K+ in Reddit karma over Q2 2021. It was clear that <strong>@Danglewood</strong> was having an impact on driving traffic and user engagement by posting data and his personal research with screenshots of Gamestonk Terminal.</p>\n<p>In the future, <strong>our report feature will allow easy sharing of this information</strong>, I already can’t wait for this. Through a combination of humour and truths, he was engaging the audience’s curiosity by providing them with ways to filter out the ever-present noise within stock market information.</p>\n<p>It made sense to bring this approach to <a href=\"https://twitter.com/gamestonkt\" target=\"_blank\" rel=\"noopener noreferrer\">our Twitter</a> feed which has since transformed and now offers insights, educational nuggets, and data as well as presenting new features. The end result speaks for itself!</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2021-11-17-handing-your-twitter-account-to-your-most-avid-community-member_4-c0f1649da83991a61302931d96c923d9.webp\" width=\"1192\" height=\"1550\" class=\"img_ev3q\"></p>\n<p>On your end, what is your opinion? And why do you 100% agree that this was the best decision?</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/handing-your-twitter-account-to-your-most-avid-community-member",
            "title": "Handing your twitter account to your most avid community member",
            "summary": "Handing over the Twitter account of Gamestonk Terminal to an active community member and the impact it had on the project's growth and engagement.",
            "date_modified": "2021-11-17T00:00:00.000Z",
            "tags": [
                "community-building",
                "twitter",
                "open-source",
                "gamestonk-terminal"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/the-start-of-my-machine-learning-journey",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2021-11-07-the-start-of-my-machine-learning-journey.webp\"></p>\n<br>\n<p>The start of my journey into the world of Machine Learning, from learning Python to understanding the underlying mathematics of ML algorithms.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>During my studies at <a href=\"https://www.imperial.ac.uk/\" target=\"_blank\" rel=\"noopener noreferrer\">Imperial College London</a> - 3ish years ago - I was introduced to the topic of Machine Learning, an area that I had always been interested about.</p>\n<p>At that time, not only I didn't know python, as <code>from sklearn.decomposition import PCA</code> wasn’t allowed. Therefore, we had to write the PCA (and other) algorithms in Matlab from scratch, which was great because it exposed us to the maths behind each algorithm.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2021-11-07-the-start-of-my-machine-learning-journey_1-da0362df61f08a91e53416f4deb31c3d.webp\" width=\"720\" height=\"720\" class=\"img_ev3q\"></p>\n<p>The gif above is from my graduation at Royal Albert Hall with a MSc. in Control Systems with Distinction.</p>\n<p>After concluding my thesis (and paper): \"<a href=\"https://ieeexplore.ieee.org/abstract/document/8796226\" target=\"_blank\" rel=\"noopener noreferrer\">Energy savings from an Ecological Cooperative Adaptive Cruise Control: a Battery Electric Vehicle platoon investigation</a>\", which was presented at the 2019 European Control Conference in Napoli, I had finally time to focus on Machine Learning topics during my spare time through late hours and into weekends.</p>\n<p>I started by doing the famous MOOC <strong>“Machine Learning - Andrew Ng”</strong>. Saying that the course was good is an understatement. I ended up spending a long time on the course as I was taking notes and revising daily; I was still behaving like a university student even without the exam at the end! Not only the theory is really detailed, but the coursework in Matlab allowed me to understand what’s going on under the hood. Given that I was already a heavy Matlab user, due to its usage throughout my entire academic journey, I could focus on the ML section.</p>\n<p>After this course, I knew that I had learnt a lot, but I also knew that if I wanted to use ML for real-applications, I’d have to learn Python. Given that I knew Matlab, I choose to start reading a python book that had Data Science application in mind. Hence, I started reading <strong>“Python Data Science Handbook”</strong>. This, along with several hours of practicing on available datasets, has taught me pretty much all I know about Numpy, Pandas and Matplotlib. Although this book also contains a last chapter with ML algorithms, these are rather brief.</p>\n<blockquote>\n<p><em>In my previous job at Nurvv, where I worked as Sensor Fusion Engineer, I developed a python analysis tool that parsed all the raw data from a running session and conveyed that information into meaningful plots. This allowed us to analyse whether a run was successful from the Firmware side of things, and this was critical for our development. This tool was created mainly from the knowledged gathered from the book mentioned above.</em></p>\n</blockquote>\n<br>\n<p>Following this, I was rather confident with my Python skills. Therefore, I wanted to crack-on learning how to use ML algorithms with Python through the beauty of imports. It comes without saying that I had to start from the best-seller <strong>“Hands-on Machine Learning with Scikit-Learn, Keras and TensorFlow”</strong>. This book was what I was expecting and more. From time to time, when I’m working on personal projects, I still flick through it. This book also allowed me to develop many more personal projects (most of them public in <a href=\"https://github.com/DidierRLopes\" target=\"_blank\" rel=\"noopener noreferrer\">my GitHub</a>, as I’m a big Open-Source fan — you should know that as I made <a href=\"https://github.com/GamestonkTerminal/GamestonkTerminal\" target=\"_blank\" rel=\"noopener noreferrer\">Gamestonk Terminal</a> repository public).</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2021-11-07-the-start-of-my-machine-learning-journey_2-50c7578260250056f8921f76d1d30a7d.webp\" width=\"1358\" height=\"836\" class=\"img_ev3q\"></p>\n<p>The project that has been my biggest challenge was working with a friend on his PhD thesis entitled <em>“Modelling and Forecasting of Time-Series: A data science approach that compares classic methodologies with deep learning methodologies”</em>. Not only interpreting and discussing results but writing the code behind it. S/O to the resources: <strong>“Forecasting: Principles and Practice”</strong> and <strong>“<a href=\"https://machinelearningmastery.xn--com-9o0a/\" target=\"_blank\" rel=\"noopener noreferrer\">https://machinelearningmastery.com”</a></strong>. Without these, this work would have been much harder.</p>\n<p>Throughout my short journey, I followed many people related with DS. People that I thought that in some shape or form added value through their posts. One of these, was Andriy Burkov. I remember when he started talking about creating the <strong>“The Hundred-Page Machine Learning Book”</strong> and specifically, I remember his Linkedin's poll to select the colour of one of the bubbles for his books' cover. I voted purple; the result was yellow. So, I took the freedom to fix the cover of his book, as you can see below.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2021-11-07-the-start-of-my-machine-learning-journey_3-050b9f57bc9aa3f0688f2e3e05a01566.webp\" width=\"1400\" height=\"1383\" class=\"img_ev3q\"></p>\n<p>My gecko Reidid on “The Hundred-Page Machine Learning Book”​, in order to keep industry standards of ML books with reptiles.</p>\n<p>I really enjoyed his book since it can explain everything, while keeping it simple and short. As I learned at University, <em>Keep It Simple, Stupid</em>. Also, his book is distributed in a “read first, buy later” principle. This meant that I was able to flick through the content of the book before buying it. Personally, I think this should be adopted more often, at least for technical books.</p>\n<p>Finally, last summer, while on holiday in Portugal, I read <strong>“Approaching (almost) any machine learning”</strong>, which I found to be great for people that have read about the theory but were wondering where/how to apply it.</p>\n<p>The next ML books in my list are:</p>\n<ul>\n<li><strong>Deep Learning</strong> — Aaron Courville, Ian Goodfellow, and Yoshua Bengio</li>\n<li><strong>The Elements of Statistical Learning</strong> — Jerome H. Friedman, Robert Tibshirani e Trevor Hastie</li>\n<li><strong>Pattern Recognition and Machine Learning</strong> — Christopher Bishop</li>\n<li><strong>Understanding Machine Learning: From Theory to Algorithms</strong> — Shai Ben-David and Shai Shalev-Shwartz</li>\n</ul>\n<p>Let me know if you think these are good books, or if there are others that you’d recommend.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/the-start-of-my-machine-learning-journey",
            "title": "The Start of my Machine Learning journey",
            "summary": "The start of my journey into the world of Machine Learning, from learning Python to understanding the underlying mathematics of ML algorithms.",
            "date_modified": "2021-11-07T00:00:00.000Z",
            "tags": [
                "machine-learning",
                "python",
                "data-science",
                "education",
                "self-learning"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/an-unusual-journey-learning-about-nns-for-a-phd-thesis",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2021-10-22-an-unusual-journey-learning-about-nns-for-a-phd-thesis.webp\"></p>\n<br>\n<p>An unusual journey of learning about Neural Networks for a PhD thesis. This blog post details the author's experience of assisting in the programming aspect of a PhD thesis, focusing on the study of various models and their forecasting performance.</p>\n<p>The open source code is available <a href=\"https://github.com/DidierRLopes/UnivariateTimeSeriesForecast\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>On 14th February of 2019, my previous Maths and Statistics teacher — <a href=\"https://www.linkedin.com/in/filipe-r-ramos-a66242143/\" target=\"_blank\" rel=\"noopener noreferrer\">Filipe</a> - sent me a messaged because of a Linkedin post I shared about work I was doing in python.</p>\n<p>It turns out that Filipe was looking for someone to help him with his PhD thesis, in specific, with the programming side of it. The challenge was to study diverse models (from classical to neural networks) and assess their forecasting performance. Since time series prediction was always a topic that I found fascinating and hadn’t had time to study, I thought this would be the perfect timing to do so.</p>\n<p>So from February 2019 onwards, this exciting journey started. I was working full-time so in order to be able to take part in this, I was only sleeping 4/5h a day. I started reading a lot of books and practicing my python coding skills in order to be more helpful. Then around June, we started working together on the code. We had around 2–3h discussions a couple times a week where we would discuss the point of the situation code-wise and where we wanted to be, we kept in touch about this every day.</p>\n<p>From the repo, which is open source <a href=\"https://github.com/DidierRLopes/UnivariateTimeSeriesForecast\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>, you can see that we explored: Exploratory Data Analysis; ARIMA and SARIMA; Exponential Smoothing; Deep Neural Network. The final part of this work consisted in an innovative approach to tackle an univariate time series, which you can find <a href=\"https://github.com/DidierRLopes/UnivariateTimeSeriesForecast/blob/master/DNN_ourApproach.ipynb\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>. On top of that, a library of cross-validation for Neural Networks was developed, which is now being used in real data science applications, see <a href=\"https://github.com/DidierRLopes/timeseries-cv\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<p>The work, which took around 1 year to complete, can be divided into 3 distinct phases:</p>\n<ul>\n<li>The <strong>coding</strong> phase lasted around 3 months. I would write the code, test the code and then touch base with Filipe to ensure we were going in the right direction.</li>\n<li>The <strong>tweaking and analysis phase</strong> took around another 3 months. Here, Filipe took the code I had completed and analysed multiple time series with different trends and seasonalities; tweaked different models; trained and validated these; and started interpreting results. In this phase, me and Filipe would discuss the code from a pragmatic point of view, and improve it based on what Filipe wanted to see/analyse. This phase was so intense that Filipe flew out to London twice to meet me, almost over a period of 1 month.</li>\n<li>The <strong>writing of the thesis phase</strong> took an additional 6 months. Here Filipe basically translated the results and analysis seen on the notebook of the thesis, wrote a full theoretical background on the models used and interpreted the applicability of these.</li>\n</ul>\n<p>The full work, <em>“Data Science in the Modeling and Forecasting of Financial timeseries: from Classic methodologies to Deep Learning”</em>, can be found in <a href=\"https://ciencia.iscte-iul.pt/publications/data-science-na-modelacao-e-previsao-de-series-economico-financeiras-das-metodologias-classicas-ao/82703\" target=\"_blank\" rel=\"noopener noreferrer\">here</a> or stored in <a href=\"https://repositorio.iscte-iul.pt/handle/10071/22964\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<p>During this time, Filipe was also working full-time as he was a teaching assistant in three different universities. In spite of the adversities, Filipe achieved an impressive approved with “<em>unanimous distinction</em>” (maximum classification) from ISCTE Business School, Lisbon, Portugal.</p>\n<p>My character waiting for people to join my chatroom to discuss our poster.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2021-10-22-an-unusual-journey-learning-about-nns-for-a-phd-thesis_1-d8856564ea417a1dc5eb16b5ccdb404c.webp\" width=\"1400\" height=\"793\" class=\"img_ev3q\"></p>\n<p>Last week, at XXV Congress of the Portuguese Statistical Society (SPE 2021), we presented:</p>\n<ul>\n<li>A poster that you can find <a href=\"https://www.researchgate.net/publication/355360806_Forecasting_models_for_time-series_a_comparative_study_between_classical_methodologies_and_Deep_Learning\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>, titled: <em>“Forecasting models for time-series: a comparative study between classical methodologies and Deep Learning”</em></li>\n<li>A presentation that you can find <a href=\"https://www.researchgate.net/publication/355360897_Explorando_o_poder_da_memoria_das_redes_neuronais_LSTM_na_modelacao_e_previsao_do_PSI_20\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>, titled: <em>“Explorando o poder da memória das redes neuronais LSTM na modelação e previsão do PSI 20”</em></li>\n</ul>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2021-10-22-an-unusual-journey-learning-about-nns-for-a-phd-thesis_2-f432421d2e9f03069a031998cd840375.webp\" width=\"1400\" height=\"1759\" class=\"img_ev3q\"></p>\n<p>The poster above was presented at XXV Congress of the Portuguese Statistical Society (SPE 2021).</p>\n<p>I started this journey with my previous maths teacher and ended it with a close friend! Excited to see what other articles/publications we’ll be working on together in the future.</p>\n<p>PS: The ARIMA/ETS/MLP/RNN/LSTM models learned from this work, consisted the basis of the prediction menu on <a href=\"https://github.com/GamestonkTerminal/GamestonkTerminal\" target=\"_blank\" rel=\"noopener noreferrer\">Gamestonk Terminal</a>.</p>\n<p>As always, feel free to provide feedback!</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/an-unusual-journey-learning-about-nns-for-a-phd-thesis",
            "title": "An unusual journey learning about NNs for a PhD thesis",
            "summary": "An unusual journey of learning about Neural Networks for a PhD thesis. This blog post details the author's experience of assisting in the programming aspect of a PhD thesis, focusing on the study of various models and their forecasting performance.",
            "date_modified": "2021-10-22T00:00:00.000Z",
            "tags": [
                "phd-thesis",
                "neural-networks",
                "python",
                "time-series-forecasting"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/how-i-created-a-bot-in-python-to-participate-in-nft-giveaways",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2021-09-30-how-i-created-a-bot-in-python-to-participate-in-nft-giveaways.webp\"></p>\n<br>\n<p>In this blogpost, I share how I created a bot in Python to automate participation in NFT giveaways on Reddit. The bot simplifies tasks such as upvoting posts, commenting, and opening Opensea links to favourite artwork.</p>\n<p>The open source code is available <a href=\"https://github.com/DidierRLopes/GiveawayNFTbot\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>Lately I’ve been looking into NFTs. I’ve observed that more and more people are trying to innovate and create their own pieces of art. Some of them are impressive, some of them aren’t. But,</p>\n<blockquote>\n<p><em>Beauty is in the eye of the beholder — Margaret Wolfe Hungerford</em></p>\n</blockquote>\n<br>\n<p>However, in my humble opinion, what distinguishes some art from others, is most of the time not the art itself but the community around it. For example, when everyone starts talking about the ‘new best thing’ you feel more pressure to get involved.</p>\n<p>Because of this dynamic, creators are investing in ways to increase their collectibles popularity by building their community. A great example is <a href=\"https://parallel.life/\" target=\"_blank\" rel=\"noopener noreferrer\">ParallelNFT</a> and the dystopic story that is being created around their cards — in their case, it’s fairly easy to understand that once a big community is formed around such cards, video games, movies and even series are on the table. For the first time ever, we would go from selling collectibles to creating some form of entertainment. A whole new industry in the making.</p>\n<p>However, not every digital creator has the resources to create a full concept around their cards. Does this mean that they can’t create a community around it? No. But they must find other ways. One of the most popular ways I’ve seen is through giveaways. Similar to what small clothing brands do to increase their popularity. This is a great tactic in my opinion, since giveaway not only give you a bigger audience (people that participate and re-share content) but it makes the cards have multiple owners. This, as a result, makes the collection more attractive for NFT collectors.</p>\n<p><em>When demand exceeds supply</em>, <strong>prices tend to rise.</strong></p>\n<p>And these creators are using Reddit as the platform of their giveaways.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2021-09-30-how-i-created-a-bot-in-python-to-participate-in-nft-giveaways_1-b44b69bbb12461c5ea92bcb46732986a.webp\" width=\"1282\" height=\"1144\" class=\"img_ev3q\"></p>\n<p>When scrolling through reddit you will notice that all these posts have certain things in common:</p>\n<ul>\n<li>They ask for an up-vote on the post</li>\n<li>A comment with your wallet address</li>\n<li>To favourite their artwork</li>\n<li>They may also ask to you to join their Discord</li>\n<li>For a follow on their Twitter or Instagram</li>\n<li>If you can retweet or share a story</li>\n</ul>\n<p>These are things that take time, and a bot can perfectly do this. Therefore, I wrote a <a href=\"https://github.com/DidierRLopes/GiveawayNFTbot\" target=\"_blank\" rel=\"noopener noreferrer\">giveaway NFT bot</a> to simplify my work. Now I just sit down and read robot vacuum reviews while the bot: upvotes, comments and opens their Opensea link for me to favourite their artwork.</p>\n<p>I’ve already won multiple NFTs with this, which is exciting— you never know where the next <a href=\"https://twitter.com/cryptopunksbot\" target=\"_blank\" rel=\"noopener noreferrer\">CryptoPunks</a> are at.</p>\n<p>There’s actually 1 collection that I particularly like and believe has a lot of potential, it’s called <a href=\"https://opensea.io/collection/crypto-cartooneaters\" target=\"_blank\" rel=\"noopener noreferrer\">CryptoCartoonEaters</a> and due to the uniqueness of each collectible (only 100 made), I really think it has a great potential. I acquired my favourite cartoon as a kid: Goku Eating a Burger.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"data:image/webp;base64,UklGRlobAABXRUJQVlA4IE4bAABwyQCdASr0AfQBPjEYiUMiIaEVPBygIAMEsrd8FDRDFAJ3NpgPSVmjxmABCF8ATl1Rv6f8zPCZkP3L+i/Ln+5fuv3SHfXiT41v53k78R/pfOe9n/MP+L+lX7o/Lv/Df7n/Yf1z5M/5j+8+xP/j/5L+GPtseyT+kf871Rf0f/G/tP7sH+W/cbsPP6h/h///7VXre+jn/JvSr/33tc/sH+5Xw6fqV/9tad8Z/zv8Vf3F+suA+wb+grwD6Ovd/rP6N/2z8cPvl+6f5T8Ovwe9bXcF/qH5D/knmFP7x+h/9z/JL7TPXv+H+AHMEf4D9G/8P+////+yv6n/n+7l6in8J/0H5nf3v3d/5T9HP8r/Y////4PypmB/6r+7/xj/3f5D5FP//1m36Df///9BqVz9EeHbo8nXFHm9z9Ba7QQG0gwrn6I8O3SDNu5MRGW2/4iRTMVpCJEpQnTYtytenW3P0R4dukGbec27jfTRYn/j2nt886H7xNXaUvIzPjVVjIkw7ec285t5zbzm3epUq5DidyDrzkMiwNVgB+0zE9CTlb9YZ87lLgTyiQYVz9EeFCc6tG6IORxI7YFAhwd84YGmWu0gwnpJM9DAypkVMQGV2n7ulG1+CZJIVQ+l5bDA3UvSx1SzBBQ4Jxk6kZNBrmq+Wtk1L5n2ozmw4LdAVGpvBZ39EeHWYVzn2PkeKwksyZMEkIrhY65Xzm1CI1dEN+lpk7ctELorQYVz9Edrnjli2jJXpLgaNBJBV7olxhET1hu4Og+3XU2Zrojw7dIVhijh26R09VU1TuO5THA+liNevUrDQu6QZt5zKHJC4rCcez6EGiWjedwB25J5vAF+TopW0cRxcsIdIu92kMvIeXg9x5S6SsBaHPtVJj4rNp2WzJNr6OCPSDiMJTQPe8ff9c74o342sKwzfaYVn5oViyyn39B+QB8LFbG0rSMqCCpwjyJBjcthvOV+ncW+AbQYVty2/nQcDIRGEhiTiLnlYf27adF715VGuAfcu/QlDCCPaNteoW7kh6xyir3zpiQYnjbTfPHszrWmPY1f4RP2kBjoL9slIDF2fXoTtN3O8vb/FJCp8tiNl+wbO/Qai7G1rLap19pQhbOvHtJo3aF6Mpt3acuUQPbJWlLNm0nMqoYrhJ7bb+l+sabSdSu25rNnqOseb8J9PYt73Ws7fAwbDRWASg6g4HoYchXzpbX3qrkgRJzaGyPdJ4TgX2XOFzYmET5eojhLgX0aKWW++gTtqJxGeJqDMp2UN51Pt3f1OBKTDaRaKn7otf3Z8wfhuAnP+B7iqkxq5LTnN7NJdRZwC+pryjH+EG1YlEbKsweExeeq5M2MTmJcsvGAc79U6O+tCHm+up2OT7ImW+t4cH+rdZWgxG/+KglTfFV91gTbGEe3VAbDAKI+Qa5y+ONYeZvRksrKei63IMrx+28XIDJ6htMNoEBi97rO1aNfmrVoyThk31dZ6yJFYFEgwrc+tWiL1SGezhdwA9+cVNtsBYQl+zcEEwD1MY3RYEGr62jibidZU+QYVz9FSPa0ilPWd21PO8RGvLHAQk6gvBv0R4dufNKz6fePBB9oG6rn4QedqbxN+oeG1v1U10R4dud5Bj49h2yUFChEgkTnmE5HR050R2bYapmZH/2TYNqLxUIzi1rUzXFrFxrkeXlQ89qbSDM91WfXcSC6Bq14GQdFDtyDrn4EpQSn1R/6ajkDyVOGH9e/8zBv39bR7YcCeUSC93/DiuCCCG68F+Hfb2rG01hllvOgaNvnN3fQj526QVyiA6Zjlf1AiW2Y26RKe99rQlZvDol/1l/1zOsuRaDDWy7VNJg75IvZOWKQfJ8Gu9IttcAaQXvJfWupnAtgX4V+xivTyBEfyec3yvd0zcJGDMzyad7Km/cW+zI4oVTTLXb//dhqSnuw4kkueCYnLTCttvqPTcwp2kF7oMTd13fnNUGznDK/ePOKYxGrZ1WJYT5t+uptxRgxkLRWc0PeZ6+roLo9HZWK3Kt3ex1gPwTgpvz3HpenDZx6bec27hDGFkyy8gTGDzzRliiWO8ZzIGwYpexG7nMy0OObuymFLNb3RS6mRjcPpqJ3wBpBhXVW0X1hG6K8oriZ9Ept+bAPc3w+hZoiVnK5+iPDtnlvSbwqRyOQw6EeHbpBm3nNu4AA/vdOf0fzdY6cu0HsUGkYDFCywABFXDZ8yqstIQorUqyQEMqS9EfcIx2hLLVmAsSEPfCFygkJk5uhLlGCUE9BupsMPEeFy990AH/KYAGhbMAO6fCh1sUHvwtOnhjm4YT5z3MA+XxEiHFiV/9+fKGAmKyL4/WukiAhT5DAqwigDWtoR5QtHdMMBRRJAARZIC+J3RgBIa6HsMi/boPouGlciH/8YteWl0SHvnRxzKZNmnksQe/25c7ChM4d1hj6u9nc14bgTr0dpmhEkOpyAAAAT1Xfwt3MY3Im1GX1XMDkZqC8S2xedSt+NQXAhAM+7NbyGfXoptUTMJ1B8MQB5FJA4EVuNS7UEH1AWLVZRgBZX8oAMhLwRN4pIxVrXJtRW5+XhYBAZc9suDS5UswT7liTzKeU0qvhzjH5C7ULkL5GcIAAAAUhFubqngpAsrHsRnbMAGNfsUQHzRPSsu1eo7uWdzQdUD7E22wI2Pn0WrHVm6SGejNtyiSIoRQ0RH0gI3kwH11+Zdm7ndKCYIVFiKr7SSbOti9Ebob7yk0DVqbg0uLPJ/MY4zWSe6xVUIR3MQBuLk/BmBS5Avo+KgNlUvDxM19l7lUhO3of9kAACfvK+Wvk8C7PavZQU8IfSobZKqklWh08bsBycvufn5/azAIW+JfbkjDzMvz8WLhmqGC4ZpdKbf07+UlRu1VvQnLQr6fW62aLW2AOCHTMoADMbxNePM3ZvGdUX7IgXRJobWaHrOlzOYMuS63GrpdIXxVAH3ZuzfyYgEauoH2NX0CWY+dqwl1IxgFDy0Aq6fBnPbabVTzJmyX9X+yR7/ZkAnujdXYSJzv3cc0eKliBUfH8ZY0Rq3HcxlsBES6Bb8Zyk5mdxn1U38/13TSdjYgNKZzAaDAUgTJr7MzSrknyt8WRo6T9sPPictRckUQ/Tb969QUuPBDOm8mk6yTqvKJxz26RbUTy37PyDJtHkkq9VFgMBfe6fN2JbKS16dYA//ynOSfmElnahlkMEnLqgQp1NyaXPeUAMG1jIc39q3dRYVNYzeuDPCfjg/6C8xfdnTmqflOdvA/49pABgMziuK29neTTQYgZHQUms+iI7h8atqZvunzBPYFj+BVcnSvPI8IPDRBgTvFF/U/Sd6zwWLAHm/NcqAh9g0RjY3DJn5yvZ9pObN7ef5OkraUMbeKOjhHk9+nTMdnWCJyASlSE2rKUx372/11n3agghqdfp2iwdCRr1Mb9CysqNbfLnTdnSTWC9jP3WKX8ChUpA3lwiVXlZiYAGjB4OjC5ZXL0J1hveCvBH0KlvgAAquyT5q7ylURe//913h8KQTmaHIWMm7/ogkob2BGIOkHYq3BjHdUm8NQopypLk3BJxbXcQTyDGY1oRJaBFAjk5cQgZY0xJw2MTlvlafG4AAuMRGgGpDuAipDUV/y/wjBgdtAa2QsC/8mmUj6/qZODJsNHvOYA3Eb8GJJyKCJMVRB0CV1WN3m4V3T97WVxRVti3UZ5/RfQvRQqlXde+7HP8zn5LOgfWiXmxgIQ9L1U2Zz0RVuNcc+0hJMAT7PCt0c2gwbZZxJ/27ErMsSs248GtAlT+zMg7dYsfBQtPgANgvpyKXZCkIGerCSMpGxoqHmH+7y7D1yBQGTbieYK/cj0p/jlJay/4O6eZFlUE3k81Y2hGXUK6OGcWmRVcQ8M0A/A0L2E9UtncIVVBPfMhdnKwCyMYoOvgDA2wATW51XP0C17Wg+efFEAm6tFWdicgrdCOKxK7aNPqEoi9qQ3YoT4qRKr11NfOEFHJ+9ewgG5CUBvbC1NwKPgbJ9rULkUZWlXo41vSHpkyiyG9AMlEa6kQYe8Y+choBJJAaSrBHpVDgdRqwmYD947GzrQwv5ll3TPe0aS+PQn5H7J61CDYj5Y0kwGK9p5+3RdBIbqsvkLQGkI/lVmoJMWEEi4fJ989DG24KLAQs3uqYsCV5T1K5q/3iv0wTBu1Lf2i/wsflfs+SAEy1vciTuudPzb18VfwVNxmP6CAjWtN90ErXygS7s2ie4j8lnUps0sc7fqPZxjWC33Q0V7YNgYCMogsC4c4kfHuD0KGJ6qEtiiZc+1nQzqmYgpDXeOahTOQPlCY5ss3h2ILne64PLm3cDzYVd7iElvlPNRE9aFldRCnV2pRiETKn7hduw11BJqSAxcM00ZCjeUn+LsUUlxLVwHqkwNfw/oJRrvhrNX20JQj9csX7xjxMQf7o7AiaT/SHcgilxDS31MWAKEJBM7hfzxjlxXZ4aSGLsQHq7tT5ip8cBkXdE5FSoAvgnaGz1DHGgKbyxzYao7ZlBPBzfVzFZfAhPRmuRC3UfYCELzi0RbyT3/iKpjFUNRiP5huIXO+pZeBox2AIgG0rrxl4NwG78nblWYUnULO4UUCFkT3iMBIi0u+ZyTYpYKdF9YTx6fMHuI+pWw+E77VvZsxXiPbS+KYiUbZxroEfHrOf4gklAR+xqkdroj9pTbOveZRnKDMwGRkq7vM2MbN7I2wpOxVGT9xnWhdCxHK+14ACYnnSMU4UI/V7C+tKy+Y3aeMranyZNoGZD0CMoRo2E30IZFhWEPJTsQvFMDmUS6O5hygmcRVn6DKxLAnU5gbEhcFmcGkjvkDtMqqS6MrrK/AmoOfCCC3iopFVdOPmEjTQeNNE3GNOM5uvKSM/fKHWyKL6PWPZ0msQ6t6bsT4UDEoALKFpVc2YNb3mKvz8iiU5Zd8Qa4zILtioCGINITrMvpUBf5CeaLzDTmCuUVC4tbeVD8DCihdAQaqiP0bUlLgYgNnfvkrjRMiRjdtvrvko09OKJmoS9kDFY7XvBJMn36QRr1y7YcvYU3QtlGYVQpgr+XSzVZB63XwY1Zlfmli8qtwT9j4U/HEks5wLBf9qc9/7pJq937JTkjAvPR1HmIP9K1NBrv6VFfTZmKkad4sMs/IV023a6feJkomQ/GPrxQXfClzzuMMHwG0dOJ54iBx+AfFQOq0vH2AW8tWxUPuGOEU6bYq3g62frj070WMeHNowa39ze1HjQMidrWXYnpeaPtvX3kWeJP1cuPM3ctEtIgycVAulU5w29ubyuH7hshbAghRbMlCJDkDa7Ll1DQdeSEnoiNPnh3fXpCSBAy4k/D2G3LMaQ+p36GQuAOh971eXJLnfb5v+0Hyjtprm8xmcPYdlKCtAqSDC+x7kkLWdjJJ4wkSqNr0IuZ85lfJwYtcJkzwgLyArVVZfjpgRsi7/3jrj5fWNadcQ3YqACZ0EC4i1Hj8eioA7ct6KdwT5peA3Z6Iw7ZH+z+OUMDZYAjG3VbvODEbngOBgFCJsWGW+DgPvX6GpPqj2Ar61NwvYVRy6UuSIkFJrtGWAz6FPKF5bjtibebkt/9zNLGIQ4Oay14TObgMuvnMQXuCIVGI/YFus1S+WsuINjkgfpiunh5M+tubwjoblhtkI2jyncHMeSbuBauAo9zaJVXvsKRXgFgF34guUID7Yb9rgewPPwcua3xmv1gmrfoZb3XLdIeRvb7stu6FR5u9LEvW2SKaqvNyK1o1Bvo1E/bougp5Ngp1zchmyVZKi4/XoQeyte4I9LQqSxDywOHB9WMr2H2XGOW2i7xa9SMZjMCeh23taGQEVldW8DjoOAL3eNWykRikUJ9xbWliBx5WaoaEHTrOzw7pwsC5C4SpT1HW+4/qtrj2ME95D9Iu+j2780onHILgiwDOYghsROLDqZEsPB2l6PcssZd8spAKEpY2c5QLZ46I3WBYWbvPOPSaH625TDFp03JGdb5uxLbM9iWn8a8dFXWeJeIZrkEaHklN2jcQbmUF2tOiFp5pgEqNKN2lDsHypbrqsucGy7ajLu2I2dvB9LVbyjH1iwnpOoU/HIP/r8li7ik4ol7uO6ZsHIoWRCQah2k4npoQu/rRNYICoi/aayiG0G2Lz/IH3Nms2XTEvTs1aZ+JQCr+wJ7n0Znz+pcj7jJKQgmO2SpegKup5IQeJ7SCeN5uxLW4GUsRSuPaSlM1qheWfqGZtTe7nFJNiBHwUzGt74rqy2lGeMrMFYFgwsz2/JYvVmPrGziguEUMmIbojr9CS69CV6bsF1uTFf+wfBM/YWdRLbejgf8QaX9MzHYIr1jMZa5KUJuFUUH6f5cgG5jS0v5eOLuL8H1RKyfmAFftEUkTuFALBKsdbDReTJUX3XensOgId9XJIeOWpAlUi/sIO4/EcZ+iq28AmHLMr04to8ZW1Pkz3XmnaqAkYEfOL0vG0iYgJWEAjq3MS+JjX+j4tj14BiDCGTW+VJzOaCOQ2CYzfgdv0qipO8mgeQsPeojOW++1Jl+8ITl2fDVWFoQmUZSjzaBcRJBVe4DZ1a4jbJrUSF4QXuEfEI/5AplCOtNbrUPMM/wXQvJK/YaLscIQbgNqbAwUo3RxNIZ80FKQuacKNtzKhcLreK58l/ng/IwTrEGY00jESckq1YFOcsDs52DnkKfN08guJRpXVEKLWtP08j8ZkVZ98YOf25szNHettVA6+aBHujL+Gp/EZItJu4BwABcGY4n8QvQvzf/tR74025oAJNTqbdFH90dbDx91U4AAAAEIXjzZEHUrgqH0wTPbRBGj4/ELJgAAWsfbnCEbRV5M/NFNRaToV1ub03cq1QTSXK0L0XQVXi0Grt1g0aySJ7JXtpBpuQgqMhOSO1gDASIXWA4tLsYwY+g62YhJGXntaC/JrOcg1LhKxiTDJXhEdSj5+MaK2Hvd0vVeZRWer0iFxsgTsiUogx32qsvNMmTIzt/12Q6QUBCbSuU1tZvh+wfJPpOuoUyhXSJklsYhzrQxDccRIAiE/CVJnta1qMCXG8W9kJYhiljcVEU4s7OlHyTW9FgkK1byVREo/pFydwoSNbRILYvbbBtJcD4Q34IwOjgc+NgstowelBSdBKVtp5Rx6V0ocsWRGGc6XpyvuaRi5DksM2cU0AEz3sCjKDUhcCujZi5ib7qRlwIA7W5Qz2GpaWawC16N4nk/PdG65ZZG5BoNxXlZh9Nxg537jm4qw5ga2pS7DmqsQClGw9/YDkQha5nV3cK1vO4GggrUNuAW3ot7MuiwSbsy9RfGVF2B6kDuAEdqcH2ch0LgYWTUedP8VwzCltzjQMUydut9+6oWxa2gSAWW1Z3v69svIRhNiFmIjyu5ZUx7FaGhI2e4Grqy1KPFprkj/5X+aFNBR5uCCaj86E3ifwuB0XZP9TVhDQkKnnzdFBEHJP/+ayABoaWHXrD0hb5JxUxq5/cRpNTBUx6cpv/KhTyiOQRitCJdVgYi7v86LqQZKv5w1zuHwZhxXBheYGehZ+nteAPaa74nvLdRQrS8HZgFyEEbaOHIQ/WUEAL8FooS+9/IG9tTSZhk5OlgXmUjVEqE80XJK/cwH0e9isdeUk6bhv7vTjFNzGi4xShxl8QNA5WQCl0iZyRIrn6uzvo11IBmhvMozPEDMPHfg2PweWnp9AMVo9NB467Fn4UpbwveLUYNKEIh1yN1CfADdSROO8JtHTqDhyMM5e7MH5A1452xsiYxAall3b7RfKwhWNM+1z0q72Sb7h7kgLeo8giPiUjityZ9HxqxggLHq7mwglpxszXLodWokgYTUFH74yS/S6OOLREWIEn14pVUdUGD9m4qycrNLJJL+yCLjjxnsTxMKBjDzs0BJ2f21pruFkhaiQjdRbG8o9YTpdbtV+qlCn0WyNeq1qpv7bkYIyDMmQ9NTd/FDVQGdJ6o8GAeG37WUlVJLek0Du2npSJYGq/W8pukgpcb4A99IYueZcAfUA7EbGV9fClqkCY0CvJklohQ6PTCQAZitQ+C8c4yJ0sRaxw1eiVEH9zP6aALeEbA1vS45YfB7Z4vEBHN2SuwDC8aj+Lwlt8t8SxCMVUMPDsYF/Z/K4AeNOjiqu6GqkzcszWlSwnOQOPQ1h74cdls/+TJWmc+8nOSec8hqXYTQuixk693lk1R+c3+RRdpz4tikTB7URbf9EQ0kd7+B52iI0KuPkC+RQN5t+5cuKKh2fXm6f5FDp/IJOiqwV3lnaa8ZxnkOYyh0OoX/4iyGIQ47KaQdjDtjiF/RYursanZ5vP/YLECtUMnXoI0S3X3dq6y9YHQManWUudWkmv0WKcrF1k2SRiFVLdeOA8srqvPK6Pkqkudj5rMLIA0eE1dR/p1vOyxw/FtE1LpHi9AFAD57Px5qFRmjfpr6Ez6qcK+l7sxrcjSl1gzRKjUAmNZbAETTMW7iFN6M3cucw8Lgoo7rZAgsgXFTwsm8NuJc3K+zqxMMfoJsEtkk5fz2/AcAXmYgSe95c17vt8fNn7bDKj5eJSxpkYEo7ivHI6KCfxD61q+O3NZvBjr1CL6PblSIgAIjgwdNszCYAO7PGhpZfdv+bVN2mPPo3haKdR/IeCOJLRZRnedGVSf7IjIuauxfj033nc7OmcTqi63KP282ztVrKkwOxyTRl+yjolGZRv7xej28hAXc6dlwu67ExC6HXHQ6b898o5otXkV9ylLk407vnRiv3AcdWbgJ++U1Rt4RCKsE+SskcHWRL2gtNeHb88/SqjbNs2tQuspRw0fl0HPwbvdyRPUYqm4CHwHzqzUI46yCm1uawwwphfX73NNCgPdEVSlIPYoNB19FqJ+uPc6wgKQ0sGVX4p+2wi6/qC1aIfL53dKsgci97hJ7B8LfVbaRDwTrZvXZEVsL/efkJNJ0OrWXLgCtvTpb4rkuq/TUWLNFhtQL4J2wMPzjV1Fp1gyqyHE5JtI9vTF030TjTOtmGAa5U/EzB9OpvgAFzbnE8JOV1mBbU/UFqVApLApAD5bFiJgBONybwe8lFO7DI0X5fvde5LOBZZwcMW/8fBhoFRveI0APpIJZ13QPjUvqd7CQXs9qK+BMd5zyv2ggmTbNkgUl6NibA9iXhT3S7QxHnJ0y6F8ZzxZLyfIAYYNCBDQ4CC658NqFcKFOt4AeuGh7pApjly3PWzOTBlTz3EceF33Uj4RdhdlnE5UughpIyILlRBqD+xWd7oMPh4Ik+nGKHfwfUyyqe0SXcFgpp6cd4tOz+B1nZsMk0UzJobIjq9vmcoABPPiHV/OQkNGO+QjTG8xQMagZ6iuCoVfKwFeC00sN4lszwR4bzz3ouM4gfTrgMqQy4wLPmPlXcAABXWBW4wADChubmpyN5AkJkpAMDAAAAAAAA=\" width=\"500\" height=\"500\" class=\"img_ev3q\"></p>\n<p>Let me know if you find this article interesting, and if you used the bot as well!</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/how-i-created-a-bot-in-python-to-participate-in-nft-giveaways",
            "title": "How I created a bot in python to participate in NFT giveaways",
            "summary": "In this blogpost, I share how I created a bot in Python to automate participation in NFT giveaways on Reddit. The bot simplifies tasks such as upvoting posts, commenting, and opening Opensea links to favourite artwork.",
            "date_modified": "2021-09-30T00:00:00.000Z",
            "tags": [
                "python",
                "bot",
                "nft",
                "giveaways",
                "reddit",
                "automation"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/gamestonk-terminal-cant-stop-won-t-stop",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2021-09-16-gamestonk-terminal-cant-stop-won-t-stop_1.webp\"></p>\n<br>\n<p>Gamestonk Terminal's latest updates including Docker integration, Jupyter Lab integration, a new Hugo website, and new features. A summary of the recent developments and future plans for the open-source financial tool.</p>\n<p>The open source code is available <a href=\"https://github.com/DidierRLopes/GamestonkTerminal\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>Hey all,</p>\n<p>Do any of you know what <strong>Docker, Jupyter Lab integration, features website and new features</strong> have in common? Well this is what has been happening in <a href=\"https://github.com/GamestonkTerminal/GamestonkTerminal\" target=\"_blank\" rel=\"noopener noreferrer\">Gamestonk Terminal</a> world since last month, and <strong>MORE</strong>!</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"docker\">Docker<a href=\"https://didierlopes.com/blog/gamestonk-terminal-cant-stop-won-t-stop#docker\" class=\"hash-link\" aria-label=\"Direct link to Docker\" title=\"Direct link to Docker\">​</a></h3>\n<ul>\n<li>This has been a highly requested feature from our more experienced dev users, as it allows you to run our code in a container, pull the image and then get going with a smooth installation process. You will also be able to run Jupyer Lab from our Docker container.</li>\n</ul>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"jupyter-lab-integration\">Jupyter Lab Integration<a href=\"https://didierlopes.com/blog/gamestonk-terminal-cant-stop-won-t-stop#jupyter-lab-integration\" class=\"hash-link\" aria-label=\"Direct link to Jupyter Lab Integration\" title=\"Direct link to Jupyter Lab Integration\">​</a></h3>\n<ul>\n<li>Jupyter is on course to take over the world (see <a href=\"https://netflixtechblog.com/notebook-innovation-591ee3221233\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>).</li>\n<li>Big investment banks like JP Morgan use Jupyter too, see <a href=\"https://github.com/jpmorganchase/jupyterlab_templates\" target=\"_blank\" rel=\"noopener noreferrer\">this</a>.</li>\n<li>Professionals in the industry such as Data Scientists, Data Analysts and Machine Learning engineers are familiar with the combo dockers+notebooks. Therefore, it makes our terminal an attractive Open-Source project to devote time to.</li>\n<li>Academia students and universities will be able to use terminal data through a notebook for their projects and coursework. We’re on track to be able to achieve something on this soon!</li>\n</ul>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"hugo-website\">Hugo Website<a href=\"https://didierlopes.com/blog/gamestonk-terminal-cant-stop-won-t-stop#hugo-website\" class=\"hash-link\" aria-label=\"Direct link to Hugo Website\" title=\"Direct link to Hugo Website\">​</a></h3>\n<ul>\n<li>Link <a href=\"https://gamestonkterminal.github.io/GamestonkTerminal/\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</li>\n<li>This will not only simplify a contributor’s documentation process, but it will also let non-Gamestonkers now see the vast number of features we offer and yes, when you read “offer” this is actually an offer since the tool is <strong>completely free</strong> to use.</li>\n</ul>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"main-new-features\">Main New features<a href=\"https://didierlopes.com/blog/gamestonk-terminal-cant-stop-won-t-stop#main-new-features\" class=\"hash-link\" aria-label=\"Direct link to Main New features\" title=\"Direct link to Main New features\">​</a></h3>\n<ul>\n<li>New Dark Pool Shorts menu</li>\n<li>Refactored and improved Crypto menu!!!</li>\n<li>Dark Pool and Crypto report generation</li>\n<li>Excel Discounted Cash Flow created by a MBA student</li>\n<li>Big code refactoring to allow for contributors to easily get started with our codebase</li>\n<li>Contributing document (click here).</li>\n</ul>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"tier-2-features\">Tier 2 features<a href=\"https://didierlopes.com/blog/gamestonk-terminal-cant-stop-won-t-stop#tier-2-features\" class=\"hash-link\" aria-label=\"Direct link to Tier 2 features\" title=\"Direct link to Tier 2 features\">​</a></h3>\n<ul>\n<li><a href=\"https://sentimentinvestor.com/\" target=\"_blank\" rel=\"noopener noreferrer\">Sentiment Investor</a> data features implemented by the SI team themselves</li>\n<li>Feature/fraud indicators implemented by a MBA student</li>\n<li>Multiple plotting for economy data for more insight extraction</li>\n<li>Screener presets to not miss out on promising tickers</li>\n<li>Several new Technical Analysis indicators, e.g. Fibonacci, Fisher transform, Centre of gravity, zlma, Donchian channels…</li>\n<li>Unusual options activity</li>\n<li>Hot penny stocks in discovery menu</li>\n<li>A contributor implementation of a realtime earnings expected move, from <a href=\"https://thegeekofwallstreet.com/2021/08/03/realtime-earnings-data/\" target=\"_blank\" rel=\"noopener noreferrer\">The Geek of Wallstreet</a></li>\n<li>Several new YahooFinance commands to discover promising tickers</li>\n<li>Refactor Exploratory Data Analysis and Residual Analysis menus into a Quantitative Analysis one</li>\n</ul>\n<p>As if this wasn’t enough, we’re also working towards a <a href=\"https://github.com/GamestonkTerminal/DiscordBot\" target=\"_blank\" rel=\"noopener noreferrer\">Discord bot</a> so you can make best use of our terminal when discussing trading strategies with your friends. This was an initiative from a contributor, which just goes to show how much <strong>we rely on our community to drive our project</strong>.</p>\n<p>If you appreciate what we’re doing and want a better free and Open-Source financial tool, you should definitely star the project on our github <a href=\"https://github.com/GamestonkTerminal/GamestonkTerminal\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>, join <a href=\"https://discord.gg/Up2QGbMKHY\" target=\"_blank\" rel=\"noopener noreferrer\">our Discord channel</a>, and follow our <a href=\"https://twitter.com/gamestonkt?lang=en\" target=\"_blank\" rel=\"noopener noreferrer\">twitter account</a>. Not necessarily in that order! :)</p>\n<p>Have you been following our project and want to join our growing community? Here are a few tips on how to get started:</p>\n<ul>\n<li>Join our Discord and tell us about your experience so far</li>\n<li>Let us know what else you would like to see in the terminal</li>\n<li>You can help to improve our crypto terminal, which is 99% taken care of from our contributors!</li>\n<li>Help us add any features! You don’t know python? This may be your cue to learn with our team!</li>\n</ul>\n<p>Much love!\nGST Team &amp; Community</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/gamestonk-terminal-cant-stop-won-t-stop",
            "title": "Gamestonk Terminal — Can’t Stop, Won’t Stop",
            "summary": "Gamestonk Terminal's latest updates including Docker integration, Jupyter Lab integration, a new Hugo website, and new features. A summary of the recent developments and future plans for the open-source financial tool.",
            "date_modified": "2021-09-16T00:00:00.000Z",
            "tags": [
                "gamestonk-terminal",
                "open-source",
                "docker",
                "jupyter-lab",
                "hugo-website",
                "python",
                "finance",
                "trading"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/time-series-crossvalidation-for-nn",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2021-09-04-time-series-crossvalidation-for-nn.webp\"></p>\n<br>\n<p>This blog post discusses the creation of a Python module for splitting univariate time-series data using cross-validation techniques. The module is designed to prepare data for training, validation, and testing in a Deep Neural Network (DNN).</p>\n<p>The open source code is available <a href=\"https://github.com/DidierRLopes/timeseries-cv\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>2 years ago, <a href=\"https://www.linkedin.com/in/ACoAACK9n24BrpxWf0HMa9bL7MSHleu2YVXpI5E\" target=\"_blank\" rel=\"noopener noreferrer\">Filipe Ramos</a> my previous maths and probability teacher, knowing that I had a special interest in Data Science, challenged me to help him in his PhD thesis “<em>Data Science na Modelação e Previsão de Séries Económico-financeiras: das Metodologias Clássicas ao Deep Learning</em>”.</p>\n<p>Although we have been discussing theory, analysis and results, my main contribution was to write the Python code behind the thesis.</p>\n<p>As a result, I have written a python module that splits a given univariate time-series based on cross-validation techniques so that these can be fed to a Deep Neural Network (DNN) to extract training/validation/test errors.</p>\n<p>I know that there are examples of these online, but this was made from scratch so that we could personalise it according to the thesis’ needs, and grasp better what was at stake when performing different cross-validation techniques.</p>\n<p><strong>The idea is given a training dataset, the package will split it into Train, Validation and Test sets, by means of either Forward Chaining, K-Fold or Group K-Fold.</strong></p>\n<p>As parameters the user can not only select the number of inputs (<code>n_steps_input</code>) and outputs (<code>n_steps_forecast</code>), but also the number of samples (<code>n_steps_jump</code>) to jump in the data to train.</p>\n<p>The best way to install the package is as follows: <code>pip install timeseries-cv</code> and then use it with <code>import tsxv</code>. See the module developed <a href=\"https://pypi.org/project/timeseries-cv/\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<p>This can be seen more intuitively using the jupyter notebook: “<em>example.ipynb</em>” Below you can find an example of the usage of each function for the following Time-Series:</p>\n<div class=\"language-python codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-python codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">timeSeries </span><span class=\"token operator\">=</span><span class=\"token plain\"> array</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">[</span><span class=\"token number\">0</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> </span><span class=\"token number\">1</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> </span><span class=\"token number\">2</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> </span><span class=\"token number\">3</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> </span><span class=\"token number\">4</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> </span><span class=\"token number\">5</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> </span><span class=\"token number\">6</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> </span><span class=\"token number\">7</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> </span><span class=\"token number\">8</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> </span><span class=\"token number\">9</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> </span><span class=\"token number\">10</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> </span><span class=\"token number\">11</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> </span><span class=\"token number\">12</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> </span><span class=\"token number\">13</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> </span><span class=\"token number\">14</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> </span><span class=\"token number\">15</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> </span><span class=\"token number\">16</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> </span><span class=\"token number\">17</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> </span><span class=\"token number\">18</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> </span><span class=\"token number\">19</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> </span><span class=\"token number\">20</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> </span><span class=\"token number\">21</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> </span><span class=\"token number\">22</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> </span><span class=\"token number\">23</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> </span><span class=\"token number\">24</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> </span><span class=\"token number\">25</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> </span><span class=\"token number\">26</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">]</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><br></span></code></pre></div></div>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"split-train\">Split Train<a href=\"https://didierlopes.com/blog/time-series-crossvalidation-for-nn#split-train\" class=\"hash-link\" aria-label=\"Direct link to Split Train\" title=\"Direct link to Split Train\">​</a></h2>\n<div class=\"language-python codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-python codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">from</span><span class=\"token plain\"> tsxv</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">splitTrain </span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">import</span><span class=\"token plain\"> </span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">split_train</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> </span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">split_train_variableInput</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">X</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> y </span><span class=\"token operator\">=</span><span class=\"token plain\"> split_train</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token plain\">timeSeries</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> n_steps_input</span><span class=\"token operator\">=</span><span class=\"token number\">4</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> n_steps_forecast</span><span class=\"token operator\">=</span><span class=\"token number\">3</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> n_steps_jump</span><span class=\"token operator\">=</span><span class=\"token number\">2</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">X</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> y </span><span class=\"token operator\">=</span><span class=\"token plain\"> split_train_variableInput</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token plain\">timeSeries</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> minSamplesTrain</span><span class=\"token operator\">=</span><span class=\"token number\">10</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> n_steps_forecast</span><span class=\"token operator\">=</span><span class=\"token number\">3</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> n_steps_jump</span><span class=\"token operator\">=</span><span class=\"token number\">3</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><br></span></code></pre></div></div>\n<div class=\"flex justify-center gap-2\"><img src=\"https://didierlopes.com/blog/2021-09-04-time-series-crossvalidation-for-nn_1.webp\" width=\"50%\"><img src=\"https://didierlopes.com/blog/2021-09-04-time-series-crossvalidation-for-nn_2.webp\" width=\"50%\"></div>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"split-train-val\">Split Train Val<a href=\"https://didierlopes.com/blog/time-series-crossvalidation-for-nn#split-train-val\" class=\"hash-link\" aria-label=\"Direct link to Split Train Val\" title=\"Direct link to Split Train Val\">​</a></h2>\n<div class=\"language-python codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-python codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">from</span><span class=\"token plain\"> tsxv</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">splitTrainVal </span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">import</span><span class=\"token plain\"> </span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">split_train_val_forwardChaining</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> </span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">split_train_val_kFold</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> </span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">split_train_val_groupKFold</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">X</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> y</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> Xcv</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> ycv </span><span class=\"token operator\">=</span><span class=\"token plain\"> split_train_val_forwardChaining</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token plain\">timeSeries</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> n_steps_input</span><span class=\"token operator\">=</span><span class=\"token number\">4</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> n_steps_forecast</span><span class=\"token operator\">=</span><span class=\"token number\">3</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> n_steps_jump</span><span class=\"token operator\">=</span><span class=\"token number\">2</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">X</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> y</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> Xcv</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> ycv </span><span class=\"token operator\">=</span><span class=\"token plain\"> split_train_val_kFold</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token plain\">timeSeries</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> n_steps_input</span><span class=\"token operator\">=</span><span class=\"token number\">4</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> n_steps_forecast</span><span class=\"token operator\">=</span><span class=\"token number\">3</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> n_steps_jump</span><span class=\"token operator\">=</span><span class=\"token number\">2</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">X</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> y</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> Xcv</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> ycv </span><span class=\"token operator\">=</span><span class=\"token plain\"> split_train_val_groupKFold</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token plain\">timeSeries</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> n_steps_input</span><span class=\"token operator\">=</span><span class=\"token number\">4</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> n_steps_forecast</span><span class=\"token operator\">=</span><span class=\"token number\">3</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> n_steps_jump</span><span class=\"token operator\">=</span><span class=\"token number\">2</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><br></span></code></pre></div></div>\n<div class=\"flex justify-center gap-2\"><img src=\"https://didierlopes.com/blog/2021-09-04-time-series-crossvalidation-for-nn_3.webp\" width=\"50%\"><img src=\"https://didierlopes.com/blog/2021-09-04-time-series-crossvalidation-for-nn_4.webp\" width=\"50%\"></div>\n<br>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2021-09-04-time-series-crossvalidation-for-nn_5-90b671293ec2443bb4a483c6d6c7ff85.webp\" width=\"1400\" height=\"913\" class=\"img_ev3q\"></p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"split-train-val-test\">Split Train Val Test<a href=\"https://didierlopes.com/blog/time-series-crossvalidation-for-nn#split-train-val-test\" class=\"hash-link\" aria-label=\"Direct link to Split Train Val Test\" title=\"Direct link to Split Train Val Test\">​</a></h2>\n<div class=\"language-python codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-python codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">from</span><span class=\"token plain\"> tsxv</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">.</span><span class=\"token plain\">splitTrainValTest </span><span class=\"token keyword\" style=\"color:rgb(189, 147, 249);font-style:italic\">import</span><span class=\"token plain\"> split_train_val_test_forwardChaining</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> </span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">split_train_val_test_kFold</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">split_train_val_test_groupKFold</span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">X</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> y</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> Xcv</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> ycv</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> Xtest</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> ytest </span><span class=\"token operator\">=</span><span class=\"token plain\"> split_train_val_test_forwardChaining</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token plain\">timeSeries</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> n_steps_input</span><span class=\"token operator\">=</span><span class=\"token number\">4</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> n_steps_forecast</span><span class=\"token operator\">=</span><span class=\"token number\">3</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> n_steps_jump</span><span class=\"token operator\">=</span><span class=\"token number\">2</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">X</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> y</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> Xcv</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> ycv</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> Xtest</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> ytest </span><span class=\"token operator\">=</span><span class=\"token plain\"> split_train_val_test_kFold</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token plain\">timeSeries</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> n_steps_input</span><span class=\"token operator\">=</span><span class=\"token number\">4</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> n_steps_forecast</span><span class=\"token operator\">=</span><span class=\"token number\">3</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> n_steps_jump</span><span class=\"token operator\">=</span><span class=\"token number\">2</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><span class=\"token plain\"></span><br></span><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">X</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> y</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> Xcv</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> ycv</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> Xtest</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> ytest </span><span class=\"token operator\">=</span><span class=\"token plain\"> split_train_val_test_groupKFold</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">(</span><span class=\"token plain\">timeSeries</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> n_steps_input</span><span class=\"token operator\">=</span><span class=\"token number\">4</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> n_steps_forecast</span><span class=\"token operator\">=</span><span class=\"token number\">3</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">,</span><span class=\"token plain\"> n_steps_jump</span><span class=\"token operator\">=</span><span class=\"token number\">2</span><span class=\"token punctuation\" style=\"color:rgb(248, 248, 242)\">)</span><br></span></code></pre></div></div>\n<div class=\"flex justify-center gap-2\"><img src=\"https://didierlopes.com/blog/2021-09-04-time-series-crossvalidation-for-nn_6.webp\" width=\"50%\"><img src=\"https://didierlopes.com/blog/2021-09-04-time-series-crossvalidation-for-nn_7.webp\" width=\"50%\"></div>\n<br>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2021-09-04-time-series-crossvalidation-for-nn_8-4416a1f5014a75f62fa639561352f65b.webp\" width=\"1400\" height=\"913\" class=\"img_ev3q\"></p>\n<p>This module has not only been used for my friends’ thesis but also for a Data Science company and <a href=\"https://didierlopes.com/blog/gamestonk-terminal-the-next-best-thing-after-bloomberg-terminal\">Gamestonk Terminal</a>, that I know of :)</p>\n<p>You can check the stats of the module <a href=\"https://pypistats.org/packages/timeseries-cv\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/time-series-crossvalidation-for-nn",
            "title": "Time-Series CrossValidation for NN",
            "summary": "This blog post discusses the creation of a Python module for splitting univariate time-series data using cross-validation techniques. The module is designed to prepare data for training, validation, and testing in a Deep Neural Network (DNN).",
            "date_modified": "2021-09-04T00:00:00.000Z",
            "tags": [
                "python",
                "data-science",
                "deep-learning",
                "time-series",
                "cross-validation",
                "neural-networks"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/ranking-99-mind-f-ck-movies",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2021-08-15-ranking-99-mind-f-ck-movies.webp\"></p>\n<br>\n<p>Ranking and sorting a list of 99 mind-bending thriller movies using IMDbPy API in Python.</p>\n<p>The open source code is available <a href=\"https://github.com/DidierRLopes/SortMoviesPerRating\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>During the Christmas holidays, me and my girlfriend, after watching The Office [US] twice in a row, and knowing most of Dwight’s pranks off by heart, decided that it was time to find something worth watching.</p>\n<p>Although there’s lots of tempting series out there, we didn’t want to follow that path as we don’t like the “addiction” effect that a series has. Also, we have the same taste regarding movies, where <strong>we both enjoy complex thriller plots</strong>, that leave your mind to resonate about them long after being done with it. Personally, I consider a movie great when it still crosses my mind when trying to sleep or the day after. So, thriller movies it was.</p>\n<p>After doing a little research work I came across this list of movies on Reddit: <a href=\"https://www.reddit.com/r/coolguides/comments/geipee/99_mindfck_movies/\" target=\"_blank\" rel=\"noopener noreferrer\">99 mind f*ck movies</a>. I knew this list was good because most of my favourite movies were there, e.g. <em>The Prestige, Inception, The Usual Suspects, Primal Fear</em>, and <em>Ex Machina</em>.</p>\n<p>So, the movie list was decided, and with that, also our new year’s resolution.</p>\n<p>However, this list had 2 issues:</p>\n<p><strong>1. The list didn’t have any particular order.</strong> We would like to have the list ranked from best to worst, so that watching the best ones first will keep our motivation levels up to finish the list.</p>\n<p><strong>2. The movie title didn’t have the released year.</strong> Although we don’t particularly mind old movies, sometimes we’re just not in the mood to watch a B&amp;W screen, or poor image resolution.</p>\n<p>Therefore, while Meg was busy, I was on a role to hack something that would both sort the list based on IMDB ranking, and add the release years to the titles.</p>\n<p>In a couple of minutes, I was already playing with <a href=\"https://imdbpy.github.io/\" target=\"_blank\" rel=\"noopener noreferrer\">IMDbPy API</a>. This allowed me to have the sorting algorithm running in the background pretty quick. Within the hour, we already had our sorted movie list. Which I have attached below for future reference.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2021-08-15-ranking-99-mind-f-ck-movies_1-3fbc90166aed9c60e60743d85f7c3b76.webp\" width=\"1400\" height=\"570\" class=\"img_ev3q\"></p>\n<p>The first movie of the list that none of us had already watched was the movie <a href=\"https://www.imdb.com/title/tt1255953/\" target=\"_blank\" rel=\"noopener noreferrer\">Incendies</a>. After having watched this movie, I can already tell you that sorting out this list was worth it. Definitely mind blowing, and a great watch.</p>\n<p>As usual, you can find the source code on my github: <a href=\"https://github.com/DidierRLopes/SortMoviesPerRating\" target=\"_blank\" rel=\"noopener noreferrer\">SortMoviesPerRating</a>.</p>\n<p>Hope you enjoyed this read!</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/ranking-99-mind-f-ck-movies",
            "title": "Ranking 99 Mind f*ck movies",
            "summary": "Ranking and sorting a list of 99 mind-bending thriller movies using IMDbPy API in Python.",
            "date_modified": "2021-08-15T00:00:00.000Z",
            "tags": [
                "movies",
                "thrillers",
                "imdbpy",
                "python",
                "sorting-algorithm"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/k-means-clustering-to-visit-a-new-city",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2021-08-01-k-means-clustering-to-visit-a-new-city.webp\"></p>\n<br>\n<p>In this blogpost, I share how I used the K-means algorithm to plan a visit to London. The algorithm helps to decide which attractions to visit based on the number of days of the visit and the GPS coordinates of the attractions.</p>\n<p>The open source code is available <a href=\"https://github.com/DidierRLopes/LondonVisit\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>Usually when I book a weekend getaway, I spend quite some time doing 2 things:</p>\n<ul>\n<li>Writing down the main attractions I want to see</li>\n<li>Depicting the travel path to maximise efficiency and see the most in less time (I’m a bit of an efficiency freak myself, sorry)</li>\n</ul>\n<p><strong>This repository aims to decide which attractions to visit in London as a function of the number of days that you will be visiting, by applying K-means algorithm.</strong></p>\n<p>As input you need to give the GPS coordinates of the main attractions you want to visit during your stay, and the number of days you are planning to visit. Notice that attractions that are not within the map screenshot boundaries will be discarded. See disclaimer below.</p>\n<p>The K-means algorithm will interpret: List of GPS coordinates of the main attractions that you want to visit as 2D samples, after converting to UTM. Number of days of the visit as Number of clusters.</p>\n<p>Of course, this is rather unrealistic because of several reasons, such as:</p>\n<ul>\n<li>Not taking into account if they want to just pass by the London Eye, or have a ride on it;</li>\n<li>Assumes that we are in a no man’s land since it completely bypasses the existence of other buildings, roads, …;</li>\n<li>Does not consider altitude, even though London is rather plane;</li>\n<li>Does not consider the number of attractions that one can possibly do per day;</li>\n<li>Plus, if there was to be an attraction really far from the centre, it may happen that the algorithm considers an entire day for it (this would depend upon kernel initialisation)</li>\n</ul>\n<p>Nonetheless, I think this is a funny exercise, and if I were to select the areas to visit by myself, <strong>it would most likely be a similar choice to the one taken by K-means</strong>.</p>\n<p><strong>Disclaimer</strong>: I did not know how to use Google API (neither wanted to pay for a key to be fair) hence I just took a screenshot of google maps and wrote down the coordinate of the lower left corner, so that I could use it as my origin. I also took the right top corner coordinate so that I could give the map with an “accurate” scaling.</p>\n<p><strong>Note</strong>: GPS coordinates (latitude, longitude) have degrees has units, thus, explaining why the conversion to UTM coordinates, which uses meters.</p>\n<p>Immediately below you can see the result of a visit to London for 2, 3 and 4 days.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2021-08-01-k-means-clustering-to-visit-a-new-city_1-889bc0455603db701af0a50ccca9fa16.webp\" width=\"1870\" height=\"1162\" class=\"img_ev3q\"></p>\n<div class=\"flex justify-center gap-2\"><img src=\"https://didierlopes.com/blog/2021-08-01-k-means-clustering-to-visit-a-new-city_2.webp\" width=\"50%\"><img src=\"https://didierlopes.com/blog/2021-08-01-k-means-clustering-to-visit-a-new-city_3.webp\" width=\"50%\"></div>\n<br>\n<p>This project was done for fun. However, I believe that by creating a tuple per location with coordinates and estimate of time taken on each attraction, something nice could come out of this.</p>\n<p>Hope you find this interesting. Let me know your thoughts.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/k-means-clustering-to-visit-a-new-city",
            "title": "K-means algorithm to visit a new city",
            "summary": "In this blogpost, I share how I used the K-means algorithm to plan a visit to London. The algorithm helps to decide which attractions to visit based on the number of days of the visit and the GPS coordinates of the attractions.",
            "date_modified": "2021-08-01T00:00:00.000Z",
            "tags": [
                "k-means",
                "algorithm",
                "travel",
                "efficiency",
                "london",
                "gps",
                "clustering"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/minion-recipes-program",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2021-07-23-minion-recipes-program.webp\"></p>\n<br>\n<p>In this blogpost, I share how I developed a program to help my mum manage her recipes. The program allows for adding, editing, and removing recipes, and even includes fun minion icons.</p>\n<p>The open source code is available <a href=\"https://github.com/DidierRLopes/RecipesProgram\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>Once I developed the <a href=\"https://didierlopes.com/blog/household-bills-program\">Housebills program</a>, I really enjoyed the feeling of being able to create usable software from scratch. Therefore, that year during Christmas, I wanted to challenge myself to see if I could find any interesting project to do in only 1 week.</p>\n<p>I started by nagging my dad and brother for them to tell me something that would be useful to them in their daily lives. Sadly, none of them had any idea. Then, I went to the kitchen to ask my mum the same. She was busy searching recipes for xmas on her messy notebook, so she also said no.</p>\n<p>I sat there next to her thinking about what I could do, while she kept on going back and forth in her notebook searching. I don’t know if she had been reading about the binary search algorithm, or if she was just opening pages randomly. What I know is that 1 week later I did a program for her to keep her recipes. Safe to say that I saved Christmas, I guess.</p>\n<p>Note: Before the end of that year, I still upgraded the software for its version 2.0, which included more than 20 minion icons. To this day, I think she opens the program to see the minion icons more than the recipes themselves.</p>\n<p>Below it displays the interfaces used, and these correspond to: Red-Visualize; Add; Blue-Add; Green-Edit; and Yellow-Remove recipes.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2021-07-23-minion-recipes-program_1-dfb4788ca71f7addba11a0d3b93a511a.webp\" width=\"460\" height=\"525\" class=\"img_ev3q\"></p>\n<p>PS: Any resemblance with the Microsoft colour scheme is pure coincidence eheh.</p>\n<p>When adding a recipe, the following window will be displayed.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2021-07-23-minion-recipes-program_2-d6f9dfbf295cfba39d627f5d2792e18e.webp\" width=\"1366\" height=\"768\" class=\"img_ev3q\"></p>\n<p>This allows you to add both a recipe, and a category (i.e. the “Tiramisu” recipe would be within “Desserts” category).</p>\n<p>The recipe content would include:</p>\n<ul>\n<li>Name of the recipe</li>\n<li>Ingredients</li>\n<li>Preparation</li>\n<li>Comment</li>\n</ul>\n<p>When visualising a recipe, the following window will be displayed.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2021-07-23-minion-recipes-program_3-43202f25f7e329e2973005345be2d9de.webp\" width=\"1366\" height=\"768\" class=\"img_ev3q\"></p>\n<p>Where the recipe dialog box would prompt the recipes based on the category chosen on its left. Then, after selecting a recipe, the ingredients, preparation and comment would be filled out.</p>\n<p>When editing a recipe, the following window will be displayed. This is similar to the visualisation window, with the difference that the text boxes are editable, and therefore, the recipe can be improved.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2021-07-23-minion-recipes-program_4-3d7e4d1997d305a055b3e99c375954d2.webp\" width=\"1400\" height=\"913\" class=\"img_ev3q\"></p>\n<p>Note: throughout the program there are Message Dialog boxes (as shown above) that tell the user whether the recipe has been successfully (or not) edited, added or removed.</p>\n<p>Finally, in order to remove a recipe, the following window would be displayed. Where you can either delete a single recipe, or the entire category.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2021-07-23-minion-recipes-program_5-aff232d9b18ff3f73e66f57ca5d896d5.webp\" width=\"1366\" height=\"768\" class=\"img_ev3q\"></p>\n<p>The recipe database is handled in the most robust way: <strong>with plain text files</strong>, obviously.</p>\n<p>As always, hope you had a nice read.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/minion-recipes-program",
            "title": "Minion Recipes Program",
            "summary": "In this blogpost, I share how I developed a program to help my mum manage her recipes. The program allows for adding, editing, and removing recipes, and even includes fun minion icons.",
            "date_modified": "2021-07-23T00:00:00.000Z",
            "tags": [
                "python",
                "programming",
                "recipes",
                "software-development"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/household-bills-program",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2021-07-17-household-bills-program.webp\"></p>\n<br>\n<p>In this blogpost, I share my journey of creating a program to split household bills. This was my first side project where I used Java to create a GUI application.</p>\n<p>The open source code is available <a href=\"https://github.com/DidierRLopes/HouseholdBills\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p><strong>My first side project.</strong></p>\n<p>Before University, I spent most of my spare time playing counter-strike (my steam account had <strong>more than 1000 hours played</strong>, that's more than 41 entire days playing in a row). I was a decent player I'd say, you can see a compilation of \"almosts\" I've done <a href=\"https://www.youtube.com/watch?v=ocsJzNJJB50\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<p>However, I knew this wasn't the way. I realised that if I used the amount of time I was spending on online games for learning, I would have a much bigger satisfaction return. And, in the long term, my life would be better.</p>\n<p><strong>So I started studying hard.</strong> I started valuing my time more, and declined most of the parties I was invited to because I was busy working late hours. Don't get me wrong, I'm an easy person. I like to think I make friends easily. However, I just had different priorities, and partying just wasn't one of them. As my parents say: <em>\"Everything has its own time\"</em>.</p>\n<p>In my 2nd year of University, I was getting really good grades, which means that I started having discussions with the other best students in the course. <strong>That's how I met one of the smartest people I know to this day</strong>. This guy was a proper hands-on person, he didn't study half the time I did, but he was always busy with something.</p>\n<p>He had a band, developed his own personalised guitar pedals and amplifiers, and developed some apps for fun. He did this all while having excellent results at University, which is insane. That's when I realised that he was not only giving more priority to these hobbies in relation to partying or meeting people, <strong>BUT also in relation to doing courseworks or studying for exams</strong>. He'd never fail a coursework/exam, but that further study could have bumped a grade from 17 to a 19 out of 20.</p>\n<p>One day, we were meant to meet at his place to work on a coursework together, and he shown me an app that he had developed for him and his girlfriend. The app was a simple command line interface that was able to split their usual household bills (rent, water bill, food shop, cat food, etc). <strong>I found that fascinating.</strong></p>\n<p>I told him I would create one for myself. Since I had read about how to use Java to make a pretty GUI, I thought why not give this a go (although I had no idea about OOP). In addition, I didn't want my program to look the same as his, so I thought my version could be as if it was an upgrade.</p>\n<p>...</p>\n<p>After that, I was on a mission. Little did I know that after this, I never really stopped having an interest in working on new side projects.</p>\n<p>The planning steps were:</p>\n<p><strong>1. Decide main features.</strong>\nAdd new household bills to split, Give money, and See bills.</p>\n<p><strong>2.Sketch what the GUI should look like</strong></p>\n<p><strong>3. Devise data structure associated with a new Household bill split.</strong>\nThis was important for both coding, and also database management.</p>\n<p><strong>4. Work out the math associated with the splitting and giving</strong></p>\n<p>The development process was to <strong>\"divide to conquer\"</strong>. I split the tasks into several sub-tasks, and after every new little code change I was testing the code to make sure that nothing was broken. I re-iterate through design and code several times, until I was happy with my solution. Then I did some clean-up/improvements, such as: Adding pictures of the users, Login password, Frenchies as icons.</p>\n<p><strong>On a funny side note:</strong> As I didn't know how to work with DBs at that time, I used text files to save and load all the information. Meaning that if my brother ever opened one of those text files (which weren't properly hidden...), I could have passed from him owing me 100 euros to me owing him 10 million. The software was on his laptop, and I had an hardcoded password, so in theory he couldn't manually add any bill without my presence -- I guess that was enough for him to think that the product was bullet-proof.</p>\n<p>See images below of the program:</p>\n<div class=\"flex justify-center gap-2\"><img src=\"https://didierlopes.com/blog/2021-07-17-household-bills-program_1.webp\" width=\"50%\"><img src=\"https://didierlopes.com/blog/2021-07-17-household-bills-program_2.webp\" width=\"50%\"></div>\n<br>\n<div class=\"flex justify-center gap-2\"><img src=\"https://didierlopes.com/blog/2021-07-17-household-bills-program_3.webp\" width=\"50%\"><img src=\"https://didierlopes.com/blog/2021-07-17-household-bills-program_4.webp\" width=\"50%\"></div>\n<br>\n<p>You can find more information about this on my GitHub, <a href=\"https://github.com/DidierRLopes/HouseholdBills\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<p><strong>The program ended up being used for more than 3 years.</strong> Since I lived with other people other than my brother, I had to update the name/image on the program to represent that. Since I was new to coding, I didn't think about the future. Therefore, when that time came, I had to manually replace the names one by one in the code. I also had friends requesting to use the program, which lead to me adapting this to their names/figures.</p>\n<p>It was a fun project and I definitely learned loads from it. The most important thing was that I was able to do whatever <strong>I wanted software-wise as long as I dedicated enough time for it.</strong></p>\n<p>Hope you had a fun read. Thanks!</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/household-bills-program",
            "title": "Household bills Program",
            "summary": "In this blogpost, I share my journey of creating a program to split household bills. This was my first side project where I used Java to create a GUI application.",
            "date_modified": "2021-07-17T00:00:00.000Z",
            "tags": [
                "side-project",
                "java",
                "programming",
                "gui",
                "origin-story",
                "learning-to-code",
                "software-development"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/my-journey-of-memorising-a-deck-of-52-shuffled-cards",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2021-06-26-my-journey-of-memorising-a-deck-of-52-shuffled-cards.webp\"></p>\n<br>\n<p>In this blogpost, I share my journey of memorising a deck of 52 shuffled cards using the PAO system and Memory Palace technique.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>A few years back, I wanted to read a book about memory and found the best-selling book <strong>“Moonwalking with Einstein: The Art and Science of Remembering Everything”</strong> an ideal choice. I won't go into too much detail about the book which is a great read, if you don't trust me, trust Bill Gates, who called the book \"<em>absolutely phenomenal</em>\"\". But let me give you a brief sequence of events from the author and journalist of the book, Joshua Foer:</p>\n<ul>\n<li>It starts by observing the extraordinary accomplishments of mental athletes at a memory championship.</li>\n<li>Foer meets Tony Buzan, the trim 67-year-old English self-help guru who founded the <a href=\"http://www.worldmemorychampionships.com/\" target=\"_blank\" rel=\"noopener noreferrer\">World Memory Championships</a> in 1991 and who insists the brain is \"like a muscle\": exercise it and it gets stronger.</li>\n<li>Foer learns the art of memory training.</li>\n<li>He practices his memory muscles for 1 year with help of a shambling 24-year-old from Oxford who becomes his mentor.</li>\n<li>He then finds himself in the finals of the US Memory Championships, alongside 'mental athletes' who could memorise the precise order of ten shuffled decks of cards in under an hour.</li>\n</ul>\n<p>If you're interested, here's a <a href=\"https://www.theguardian.com/science/2012/nov/21/moonwalking-einstein-joshua-foer-review\" target=\"_blank\" rel=\"noopener noreferrer\">nice review</a> on the book.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"my-thoughts-after-reading-book\">My thoughts after reading book<a href=\"https://didierlopes.com/blog/my-journey-of-memorising-a-deck-of-52-shuffled-cards#my-thoughts-after-reading-book\" class=\"hash-link\" aria-label=\"Direct link to My thoughts after reading book\" title=\"Direct link to My thoughts after reading book\">​</a></h2>\n<p>After finishing this book, more than anything I was curious. Unlike Joshua Foer, I didn't want to dedicate a full year to the cause, but I still wanted to give it a go so I could look back and think: \"Here's something pretty useless for the day-to-day. Yet, how cool is that I can memorise 52 random cards?\"\".</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2021-06-26-my-journey-of-memorising-a-deck-of-52-shuffled-cards_1-7b5ecba2cf47cd4109ad430091d8a943.webp\" width=\"1080\" height=\"572\" class=\"img_ev3q\"></p>\n<p>For people who know me, they know how much I hate to leave things unfinished. Whether that's a task that I set myself, or 'just' not leaving any pizza leftover. Therefore, I knew that if I really wanted to do this, I'd have to set aside time for it, and so I did. The text under is my journey to memorise a shuffled deck of 52 cards.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"technique-pao--memory-palace\">Technique (PAO + Memory Palace)<a href=\"https://didierlopes.com/blog/my-journey-of-memorising-a-deck-of-52-shuffled-cards#technique-pao--memory-palace\" class=\"hash-link\" aria-label=\"Direct link to Technique (PAO + Memory Palace)\" title=\"Direct link to Technique (PAO + Memory Palace)\">​</a></h2>\n<p>The mnemonic \"<strong>Memory Palace</strong>\" technique that I was about to use was referred to on the aforementioned book. The ancient mnemonic technique was first practiced by Simonides of Ceos over 2,500 years ago. When googling the term, the definition is:</p>\n<p><em>A Memory Palace is an imaginary location in your mind where you can store mnemonic images. The most common type of memory palace involves making a journey through a place you know well, like a building or town. Along that journey there are specific locations that you always visit in the same order.</em></p>\n<p>The mnemonic images would be conceived using the famous PAO system. This term means:</p>\n<p><em>The Person-Action-Object System (or \"PAO\" System) is a popular method for memorising long random numbers and decks of playing cards. … Some people assign arbitrary images to the numbers without any phonetic conversion. The digits are usually chunked in 2 or 3 digits and then placed into loci in a Memory Palace.</em></p>\n<p>The idea is to take advantage of what we humans are best at, photographic memory.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"the-journey-of-memorising-a-shuffled-deck-of-52-cards\">The journey of memorising a shuffled deck of 52 cards<a href=\"https://didierlopes.com/blog/my-journey-of-memorising-a-deck-of-52-shuffled-cards#the-journey-of-memorising-a-shuffled-deck-of-52-cards\" class=\"hash-link\" aria-label=\"Direct link to The journey of memorising a shuffled deck of 52 cards\" title=\"Direct link to The journey of memorising a shuffled deck of 52 cards\">​</a></h2>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"1-create-your-own-personal-pao-system\">1. Create your own personal PAO system.<a href=\"https://didierlopes.com/blog/my-journey-of-memorising-a-deck-of-52-shuffled-cards#1-create-your-own-personal-pao-system\" class=\"hash-link\" aria-label=\"Direct link to 1. Create your own personal PAO system.\" title=\"Direct link to 1. Create your own personal PAO system.\">​</a></h3>\n<p>For each card of the deck you have to have an associated <em>Person</em>, <em>Action</em> and <em>Object</em>. It's useful to have the least possible rules, and have these intersecting simultaneous cards, so that there's less to memorise. Here's how I did it:</p>\n<ul>\n<li>Define a <strong>category</strong> for each <strong>suit</strong> (e.g. Hearts represents friends)</li>\n<li>Define <strong>something</strong> for each <strong>type</strong>.<!-- -->\n<ul>\n<li>From 1 to 10 I've defined the starting letter of the person (e.g. Card 7 represents a person with name starting with letter K or C).</li>\n<li>For the court (Queen, Jack, King) I've defined them as a powerful male/female. (e.g. King is the GOAT of the category).</li>\n</ul>\n</li>\n</ul>\n<p>Below you can see what the table looks like:</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2021-06-26-my-journey-of-memorising-a-deck-of-52-shuffled-cards_2-833f19daddb6300983c5f14dcfceb21b.webp\" width=\"1280\" height=\"720\" class=\"img_ev3q\"></p>\n<p><strong>Note:</strong> The Person is the main existing link, hence it needs to be something that you think of immediately when the category and the type of the card is known.</p>\n<p>I had to change my cards several times as some of the PAO's I had weren't memorable enough, either because the name was too common, or because I didn't relate that much to this person.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"2-memorise-each-card-with-its-pao-system\">2. Memorise each card with it's PAO system<a href=\"https://didierlopes.com/blog/my-journey-of-memorising-a-deck-of-52-shuffled-cards#2-memorise-each-card-with-its-pao-system\" class=\"hash-link\" aria-label=\"Direct link to 2. Memorise each card with it's PAO system\" title=\"Direct link to 2. Memorise each card with it's PAO system\">​</a></h3>\n<p>Once the table above is filled in, the next step is to associate each card with it's <strong>Person-Action-Object</strong>. I find that as long as you can remember the person name of the card by doing the cross between category and type, the action-object comes easily.</p>\n<p>For instance:</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2021-06-26-my-journey-of-memorising-a-deck-of-52-shuffled-cards_3-a00eefab808cdb824e374cf8b7790ae9.webp\" width=\"1400\" height=\"537\" class=\"img_ev3q\"></p>\n<p><strong>Jack ♦: Einstein — Writing Equations — Blackboard</strong></p>\n<ul>\n<li>When I see a <strong>Diamond</strong>, I know we are in the <strong>Celebrities</strong> category. Since this is a <strong>Jack</strong> I know it's an <strong>important person</strong>. I've selected Musk to be my GOAT, so this has to be <strong>Einstein</strong>. The <strong>writing equations</strong> and <strong>blackboard</strong> comes trivially when thinking about Einstein.</li>\n</ul>\n<p><strong>8 ♣: Floyd Mayweather — Skipping — Rope</strong></p>\n<ul>\n<li>When a <strong>Club</strong> appears, I know we are in the <strong>Athletes</strong> category. Since this is an <strong>8</strong> I know the name starts with an <strong>F or V</strong>. This promptly reminds me of <strong>Floyd</strong>. The <strong>skipping</strong> and <strong>rope</strong> come immediately, due to my own personal experiences from improving my skipping skills and looking at videos of Mayweather. I find that the more the personal and creative you get with this, the easier it is to remember.</li>\n</ul>\n<p><strong>King ♠: Goku — Powering up — Blonde Hair</strong></p>\n<ul>\n<li>If I see a <strong>Spade</strong>, I know we are in the <strong>Cartoon</strong> category. Since this is a King I know that this character is the <strong>GOAT</strong>. Which immediately triggers my brain to Goku, since it used to be my favourite cartoon as a kid. Trivially, comes the powering up as action, and the blonde hair as object.</li>\n</ul>\n<p>In order to remember all the cards, my trick was to have a deck of cards where on the back of each card I wrote its own PAO. So that if I didn't remember, instead of looking at the table, I could look at the back of the card. However, I find it important to sometimes not quit trying to remember immediately, as when you initially struggle to remember a card, when you eventually do, your brain retains this information so much better.</p>\n<p><strong>Note: At this step you may realise that you keep forgetting the same PAO card. I recommend you going back to step 1 and re-defining it.</strong> Once I did this to the cards I kept forgetting, I was in a much better position.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"3-create-your-own-memory-palace\">3. Create your own memory palace<a href=\"https://didierlopes.com/blog/my-journey-of-memorising-a-deck-of-52-shuffled-cards#3-create-your-own-memory-palace\" class=\"hash-link\" aria-label=\"Direct link to 3. Create your own memory palace\" title=\"Direct link to 3. Create your own memory palace\">​</a></h3>\n<p>This is the easiest step. I used the house I grew up in in Portugal, and decided to place 4 PAO instruments (i.e. 12 cards) per house division. Meaning that by the time I was in the first room upstairs, I was already 36 cards down the deck.</p>\n<p>Since I'm not living in Portugal, let me show you what I mean by using a picture of my current living room in London. The spots I would select in here would have been: 1. Top of table with candles; 2. Top of side table; 3. Inside my gecko's vivarium; 4. As a program on the TV.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2021-06-26-my-journey-of-memorising-a-deck-of-52-shuffled-cards_4-646868225e90507e3944d2f7b43bf894.webp\" width=\"1280\" height=\"958\" class=\"img_ev3q\"></p>\n<p><strong>Note: Make sure you always remember your memory palace spots, otherwise you may overlook them once looking for the next 3 set of cards.</strong> The way I think about this is imagining that I lost my keys, and mentally going back in time to try to understand where they could be.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"4-practice-memorising-each-set-of-3-cards-pao\">4. Practice memorising each set of 3 cards PAO<a href=\"https://didierlopes.com/blog/my-journey-of-memorising-a-deck-of-52-shuffled-cards#4-practice-memorising-each-set-of-3-cards-pao\" class=\"hash-link\" aria-label=\"Direct link to 4. Practice memorising each set of 3 cards PAO\" title=\"Direct link to 4. Practice memorising each set of 3 cards PAO\">​</a></h3>\n<p>This is where the creativity comes in. <strong>When picking 3 cards from the deck, you picture the Person of the 1st card, the Action of the 2nd one, and the Object of the 3rd one.</strong></p>\n<p>Let's imagine we've got the cards aforementioned.</p>\n<p><strong>- Card 1: Jack ♦</strong></p>\n<ul>\n<li>Einstein — Writing Equations — Blackboard</li>\n</ul>\n<p><strong>- Card 2: 8 ♣</strong></p>\n<ul>\n<li>Floyd Mayweather — Skipping — Rope</li>\n</ul>\n<p><strong>- Card 3: King ♠</strong></p>\n<ul>\n<li>Goku — Powering up — Blonde Hair</li>\n</ul>\n<p>In my brain, this would lead to</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2021-06-26-my-journey-of-memorising-a-deck-of-52-shuffled-cards_5-a90aef6c834747cdf4fdaec67658f016.webp\" width=\"437\" height=\"500\" class=\"img_ev3q\"></p>\n<p>**Note: At this point you may realise that some combos of cards don't work well together. **If this is bad enough to not make you remember the 3 card PAO, I recommend updating your PAO system to something that's easier to generalise.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"5-place-each-3-cards-pao-onto-the-memory-palace\">5. Place each 3 cards PAO onto the memory palace<a href=\"https://didierlopes.com/blog/my-journey-of-memorising-a-deck-of-52-shuffled-cards#5-place-each-3-cards-pao-onto-the-memory-palace\" class=\"hash-link\" aria-label=\"Direct link to 5. Place each 3 cards PAO onto the memory palace\" title=\"Direct link to 5. Place each 3 cards PAO onto the memory palace\">​</a></h3>\n<p>For instance, if I were to place the <strong>Einstein Skipping with Blonde Hair</strong> on the <strong>3rd spot of my living room (my gecko's vivarium)</strong>, in my head, I would picture something like this:</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2021-06-26-my-journey-of-memorising-a-deck-of-52-shuffled-cards_6-2a304996ce3a5752951238a3773eb6eb.webp\" width=\"1028\" height=\"898\" class=\"img_ev3q\"></p>\n<p><strong>Note: I recommend trying to have the 3 card PAO interacting with the environment to improve memory.</strong> In this case, I would have thought about the Blonde Skipping Einstein having to do skipping so fast that the gecko coudn't come close because the rope was going too fast. The more original/different, the more chances you have to remember this scenario.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"6-re-iterate-the-memory-palace-with-new-3-card-pao-every-time\">6. Re-iterate the memory palace with new 3 card PAO every time<a href=\"https://didierlopes.com/blog/my-journey-of-memorising-a-deck-of-52-shuffled-cards#6-re-iterate-the-memory-palace-with-new-3-card-pao-every-time\" class=\"hash-link\" aria-label=\"Direct link to 6. Re-iterate the memory palace with new 3 card PAO every time\" title=\"Direct link to 6. Re-iterate the memory palace with new 3 card PAO every time\">​</a></h3>\n<p>Instead of memorising a new 3 card PAO in a memory palace location and then moving on, I always go back to the start and think about all the previous 3 card PAO's from start. This will ensure you don't forget the oldest 3 card PAO. In fact, it will make it so that the oldest 3 card PAO are repeated more times than the newer ones, so it's all balanced out.</p>\n<h3 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"7-practice-and-practice\">7. Practice and Practice<a href=\"https://didierlopes.com/blog/my-journey-of-memorising-a-deck-of-52-shuffled-cards#7-practice-and-practice\" class=\"hash-link\" aria-label=\"Direct link to 7. Practice and Practice\" title=\"Direct link to 7. Practice and Practice\">​</a></h3>\n<p>I found out that after memorising my PAO system (which took a long time) and the memory palace, it was fairly easy to memorise the shuffled 52 deck of cards. However, it was taking me way too long to memorise it AND say it out loud.</p>\n<p>Once I started practicing more and more time started decreasing. The last time I tried, I managed to do it under 10 minutes, which is not great but I'll take it. As I mentioned, I just wanted to be able to do it, I didn't care much about the time.</p>\n<p>Also, I still needed to think about the category + type of the card every-time, I think the time to memorise the deck of cards decreases exponentially once you actually associate each card image to it's PAO. But for that you need to practice more, which for me was getting boring.</p>\n<p>...</p>\n<p>This is a different post than the ones I usually do, but I find it extremely interesting. Hence why I was keen on sharing it.</p>\n<p>Let me know if you've heard about it, or want to give this a go.</p>\n<p>Thanks for reading!</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/my-journey-of-memorising-a-deck-of-52-shuffled-cards",
            "title": "My journey of memorising a deck of 52 shuffled cards",
            "summary": "In this blogpost, I share my journey of memorising a deck of 52 shuffled cards using the PAO system and Memory Palace technique.",
            "date_modified": "2021-06-26T00:00:00.000Z",
            "tags": [
                "memory-training",
                "pao-system",
                "memory-palace",
                "card-memorization",
                "learning-techniques",
                "cognitive-skills",
                "mnemonics",
                "personal-challenge",
                "mind-hacking"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/customizable-meme-filter",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2021-06-12-customizable-meme-filter.webp\"></p>\n<br>\n<p>In this blogpost, I share my journey of creating a customizable meme filter using Python. This filter selects a random meme based on the number of people on the screen and assigns each person to a character in the meme.</p>\n<p>The open source code is available <a href=\"https://github.com/DidierRLopes/meme-filter\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>For the people who know me, they know how much I enjoy memes. I’ve got to admit, whenever I go to museums I have a lot of fun captioning artwork as memes. <strong>As I like to say, I go for the art, and I stay for the memes.</strong></p>\n<p>One day while commuting to work (you can still see the <a href=\"https://github.com/DidierRLopes/meme-filter/commit/59be427571c96350d9652922b3ab2ba52ddf18af\" target=\"_blank\" rel=\"noopener noreferrer\">first commit</a> which dates back to 10 February of 2020 and has only notes of the sketch of this idea in Portuguese) I thought:</p>\n<blockquote>\n<p>“It would be funny if there was a snapchat kind of filter where given the number of people on the screen, a random meme was selected and each person would be one of its characters”.</p>\n</blockquote>\n<br>\n<p>Since I was still improving my Python skills, I thought why not do it in Python. After 1 month, I already had the working code, however, since I was switching jobs at the time my commute time reduced drastically and so did my time to work on this. It took around 1 more month to finish the cleaning up of the script (324 lines) to be more readable, and at the same time Covid happened. <strong>The latter explains why my hair is blonde on the demo below</strong> :)</p>\n<p>Usage:</p>\n<div class=\"language-console codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-console codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">./didifilter.py — location=memes — caption=’Which meme am I?’ — initial=30 — final=50 -b — max=3</span><br></span></code></pre></div></div>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"hair_1\" src=\"https://didierlopes.com/assets/images/2021-06-12-customizable-meme-filter_1-016ef0dff15aa6e6e352b8e1cca0fb5c.webp\" width=\"1280\" height=\"720\" class=\"img_ev3q\"></p>\n<p><strong>To sum up:</strong> This program is meant to be an advanced version of the known snapchat filter where there are random images spinning on top of people’s heads. The main improvement is that you can not only select the images you want to choose from and the caption, but you can also play it with friends (recognizing more than 1 face at the same time).</p>\n<p>The best part of the script is that it is meant to be easily customizable. Any person is able to create their own filter by creating a folder with the images they want within a folder with 1, 2, … based on the number of people they are meant to be used (apart from when backwardCompatible flag is enabled), and select/specify different types of flags/parameters, e.g.:</p>\n<div class=\"language-console codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-console codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">./didifilter.py — locationFolder=celebrities — caption=’What celeb am I?’ — max=2 -v — video=”exampleVideo”</span><br></span></code></pre></div></div>\n<div class=\"language-console codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#F8F8F2;--prism-background-color:#282A36\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-console codeBlock_bY9V thin-scrollbar\" style=\"color:#F8F8F2;background-color:#282A36\"><code class=\"codeBlockLines_e6Vv\"><span class=\"token-line\" style=\"color:#F8F8F2\"><span class=\"token plain\">./didifilter.py --locationFolder=pokemons --caption=\"Who's this pokemon?\" --width=250 --height=150 --max=1 -p</span><br></span></code></pre></div></div>\n<p><strong>AND</strong>, you can also quickly tweak the code to adapt it to do something else. Here’s me <strong>pranking</strong> my girlfriend with a psyduck when the query was: “<em>Who do I look like?</em>”</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"hair_2\" src=\"https://didierlopes.com/assets/images/2021-06-12-customizable-meme-filter_2-1cf5cb014e5ed21d9b0a067e1b4fd614.webp\" width=\"1280\" height=\"720\" class=\"img_ev3q\"></p>\n<p>Hope you have a nice read and enjoy the filter. You can find the code <a href=\"https://github.com/DidierRLopes/meme-filter\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<p>Feel free to provide feedback, as always!</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/customizable-meme-filter",
            "title": "Customizable Meme Filter",
            "summary": "In this blogpost, I share my journey of creating a customizable meme filter using Python. This filter selects a random meme based on the number of people on the screen and assigns each person to a character in the meme.",
            "date_modified": "2021-06-12T00:00:00.000Z",
            "tags": [
                "python",
                "meme-filter",
                "image-processing",
                "face-recognition"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/neistpoint-project",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2021-05-23-neistpoint-project.webp\"></p>\n<br>\n<p>In this blogpost, I share my journey of starting a sustainable clothing brand, managing the project, and developing a stock management tool in C++.</p>\n<p>The open source code is available <a href=\"https://github.com/DidierRLopes/NeistpointCLI\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"context\">Context<a href=\"https://didierlopes.com/blog/neistpoint-project#context\" class=\"hash-link\" aria-label=\"Direct link to Context\" title=\"Direct link to Context\">​</a></h2>\n<p>More than 2 years ago, me and some friends started a clothing brand - <strong>NeistPoint</strong>. The logo and name is inspired by the Neist Point Lighthouse in the Isle of Skye. The motto was “<strong>For a greener future and a bluer ocean</strong>”, and the goal was to raise awareness to contribute for a sustainable environment.</p>\n<p>At <strong>Neist</strong>, we tried to not be yet another clothing brand, but actually to fill the current gap in the retail industry by producing high-quality, eco-friendly clothes at affordable prices. And we achieved that. For instance, our t-shirts are made of 100% organic ring-spun combed cotton, and they last longer than my Lacoste t-shirts — seriously.</p>\n<p>The problem is that to be profitable, you need to either increase the prices of your products, or decrease the quality, which were not things we wanted to do since they didn’t represent the value of our brand. Due to that, and the fact that the team behind our brand no longer has time/resources, we’re dropping our <strong>last ever</strong> season now.</p>\n<p>Anyway, no regrets from my side, it has been a great learning experience to understand what is involved around the creation of a brand, being a project manager internally, and doing something other than coding in my spare time. <em>Also, most importantly, ending up with a full new wardrobe of pieces that I love and that will probably last for my kids.</em></p>\n<p>Sorry for this rambling, just wanted to share this context with everyone.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"implementation\">Implementation<a href=\"https://didierlopes.com/blog/neistpoint-project#implementation\" class=\"hash-link\" aria-label=\"Direct link to Implementation\" title=\"Direct link to Implementation\">​</a></h2>\n<p>Given that our team had no experience in clothing whatsoever, and based on our needs, our steps to make this a high-quality product were:</p>\n<ol>\n<li>Get the best (environmentaly friendly) clothing material</li>\n<li>Send it to the best embroidery store in Portugal</li>\n<li>Package it and forward it onto the customer</li>\n</ol>\n<br>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2021-05-23-neistpoint-project_1-669d6644cb30874469386a760e2f193f.webp\" width=\"1060\" height=\"738\" class=\"img_ev3q\"></p>\n<p>This process was <strong>far from being optimised</strong>. In fact, pretty much everything was manual. Apart from the creation of the clothes. Therefore, we needed a Software to keep track of the products at each of it’s stages: <em>material to request, material shipping, material in stock, product to create, product creating, product in stock, and product sent</em>.</p>\n<p>Since I didn’t find anything that I liked online, and I knew how to code, I thought the best solution was to develop something myself. This way it could be adapted to perfectly fit my own requirements (advantages of being your own product owner eheh). In addition, I wanted to improve my C++ skills, so I thought, <strong>why not?</strong></p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2021-05-23-neistpoint-project_2-3b1f74bda8432afcb534a3e289cb5037.webp\" width=\"892\" height=\"704\" class=\"img_ev3q\"></p>\n<p>For 1 week or so, during my commute I worked on the <a href=\"https://github.com/DidierRLopes/NeistpointCLI\" target=\"_blank\" rel=\"noopener noreferrer\">NeistPoint Stock Managemen</a> tool. To be honest, I think it took longer to devise the architecture behind it than to actually write the code, as there were lots of things that I wanted to be taken into account. Also, the fact that the “database” is a .csv file, was intentional. This way, we could share this file between the team members.</p>\n<p>Hope someone finds this tool interesting, and gets inspired to develop their own software to meet their own project requirements. In the meantime, feel free to check us one last time on <a href=\"https://neistclothing.com/\" target=\"_blank\" rel=\"noopener noreferrer\">our website</a> or <a href=\"https://www.instagram.com/neistclothing/\" target=\"_blank\" rel=\"noopener noreferrer\">instagram</a>. You may even spot me in some of the pictures!</p>\n<p>The repository for the code can be found here: <a href=\"https://github.com/DidierRLopes/NeistpointCLI\" target=\"_blank\" rel=\"noopener noreferrer\">https://github.com/DidierRLopes/NeistpointCLI</a></p>\n<p>Thanks for reading, as always!</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/neistpoint-project",
            "title": "NeistPoint Project",
            "summary": "In this blogpost, I share my journey of starting a sustainable clothing brand, managing the project, and developing a stock management tool in C++.",
            "date_modified": "2021-05-23T00:00:00.000Z",
            "tags": [
                "neistpoint",
                "clothing-brand",
                "sustainability",
                "project-management",
                "c++",
                "stock-management"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/move-over-bloomberg-terminal-here-comes-gamestonk-terminal",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2021-04-23-move-over-bloomberg-terminal-here-comes-gamestonk-terminal.webp\"></p>\n<br>\n<p>In this blogpost, we introduce Gamestonk Terminal, an open-source project that aims to be a comprehensive tool for financial analysis and stock market research. It includes functionalities for discovering stocks, market sentiment analysis, fundamental and technical analysis, due diligence, prediction techniques, and more.</p>\n<p>The open source code is available <a href=\"https://github.com/DidierRLopes/GamestonkTerminal\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>Hey all,</p>\n<p>2 months ago I made a terminal that I had been working on my spare time, to help me on my stock research, open-source. See <a href=\"https://didierlopes.com/blog/gamestonk-terminal-the-next-best-thing-after-bloomberg-terminal\">here</a>.</p>\n<h2 class=\"anchor anchorWithStickyNavbar_LWe7\" id=\"the-motto\">The motto<a href=\"https://didierlopes.com/blog/move-over-bloomberg-terminal-here-comes-gamestonk-terminal#the-motto\" class=\"hash-link\" aria-label=\"Direct link to The motto\" title=\"Direct link to The motto\">​</a></h2>\n<p>Gamestonk Terminal provides a modern Python-based integrated environment for investment research, that allows the average joe retail trader to leverage state-of-the-art Data Science and Machine Learning technologies.</p>\n<p>As a modern Python-based environment, Gamestonk Terminal opens access to numerous Python data libraries in Data Science (Pandas, Numpy, Scipy, Jupyter), Machine Learning (Pytorch, Tensorflow, Sklearn, Flair), and Data Acquisition (Beautiful Soup, and numerous third-party APIs).</p>\n<p>As of today, and thanks to all your help and the traction created around it, the terminal is looking better than ever. Now it’s no longer only me taking care of the repo, but also 2 other experienced devs, who are adding features on a daily basis and increasing the robustness of the codebase. Feel free to wander through the FEATURES page to see what you would get out of this tool!</p>\n<p>If some of you thought it was amazing 2 months ago, you won’t believe what it looks like now. You can check out the ROADMAP for all the features that have been added since, but let me list some of them:</p>\n<ul>\n<li><strong>New</strong> Screener for stocks, which allows users to save their presets and share them</li>\n<li><strong>New</strong> Options menu</li>\n<li><strong>New</strong> Comparison Analysis to compare several tickers in their historical price, sentiment, or fundamental analysis</li>\n<li><strong>New</strong> Portfolio Optimisation that assigns stocks weights based on risk level specified by the user</li>\n<li><strong>New</strong> Exploratory Data Analysis menu that looks at historical data from a statistic point of view</li>\n<li><strong>New</strong> Residual Analysis after using a statistical model for prediction</li>\n<li><strong>New</strong> menu to provide access to your portfolio (supports Robinhood, Ally invest, Alpaca, and Degiro)</li>\n<li><strong>New</strong> Cryptocurrency, Forex, and FRED menus</li>\n<li>Prediction with backtesting</li>\n<li>Technical analysis that includes a score and a summary</li>\n<li>Due Diligence menu with data from Dark Pools, and also Failure to Deliver</li>\n<li>Sentiment analysis from news provided from collaboration with a company that provides this feature paid. Free for us!</li>\n</ul>\n<p>As always feedback is appreciated, and contributions even more so!</p>\n<p>Let’s try to reduce the gap between the amount of information that the Hedge Funds have access to in comparison with the usual retail trader.</p>\n<p>Bloomberg Terminal, we’re coming for you.</p>\n<p>Feel free to join our discord at <a href=\"https://discord.gg/Up2QGbMKHY\" target=\"_blank\" rel=\"noopener noreferrer\">https://discord.gg/Up2QGbMKHY</a>.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/move-over-bloomberg-terminal-here-comes-gamestonk-terminal",
            "title": "Move over Bloomberg Terminal, here comes Gamestonk Terminal",
            "summary": "In this blogpost, we introduce Gamestonk Terminal, an open-source project that aims to be a comprehensive tool for financial analysis and stock market research. It includes functionalities for discovering stocks, market sentiment analysis, fundamental and technical analysis, due diligence, prediction techniques, and more.",
            "date_modified": "2021-04-23T00:00:00.000Z",
            "tags": [
                "gamestonk-terminal",
                "finance",
                "stock-market",
                "programming",
                "open-source"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/momentum-football-bets",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2021-04-07-momentum-football-bets.webp\"></p>\n<br>\n<p>In this blogpost, I share how I developed an automated task to estimate the momentum of football teams for betting purposes using Beautiful Soup and Python.</p>\n<p>The open source code is available <a href=\"https://github.com/DidierRLopes/momentum-football-bets\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>This Easter, I spoke with my girlfriend’s father and there were several football matches happening that weekend, he started talking about betting on some of those matches.</p>\n<p>He carried on to explain me his betting routine, which consisted of:</p>\n<ol>\n<li>Checking the next fixtures for a specific competition: <a href=\"https://www.skysports.com/premier-league-fixtures\" target=\"_blank\" rel=\"noopener noreferrer\">https://www.skysports.com/premier-league-fixtures</a></li>\n<li>Checking the last results of each of the team and “estimate” their momentum (e.g. <a href=\"https://www.skysports.com/football/wolverhampton-wanderers-vs-liverpool/stats/429116\" target=\"_blank\" rel=\"noopener noreferrer\">https://www.skysports.com/football/wolverhampton-wanderers-vs-liverpool/stats/429116</a>)</li>\n</ol>\n<br>\n<p>Then, iterate these 2 steps for all the fixtures happening, from Premier League, Championship, League One, and League Two.</p>\n<p>Since I recently learned how to use Beautiful Soup to scrap data from web pages (see <a href=\"https://dro-lopes.medium.com/gamestonk-terminal-the-next-best-thing-after-bloomberg-terminal-a263c001a61f\" target=\"_blank\" rel=\"noopener noreferrer\">GamestonkTerminal</a>), I thought that I could create an automated task that would do all of these steps with a simple double click executable. After checking that I could extract such data from SkySports, I let him know that by the next day I would have something working.</p>\n<p>After dinner, I started working on the project, and before I went to sleep I had the first prototype working, which you can see in <a href=\"https://github.com/DidierRLopes/momentum-football-bets\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<p>On top of “his” automated task, I created a “momentum score” which tries to estimate the momentum score based on what my girlfriend’s father told me that he does. He looks into the last games of the team and see if they have a positive momentum by looking to see if they come from a winning series.</p>\n<p>So, I thought it would be good to attribute a weight to each of the last matches where the most recent match would have the biggest weight, and last one from the 6 provided from SkySports stats would have the lowest weight. Together with this weight, I thought we could use the sum of the weight to the score in case of a win, subtract in case of loss, and don’t do anything in case of a draw.</p>\n<p>So, in simple terms, if score is positive the team is likely to have been winning their last matches, if score is negative the team is likely to have loss their last matches.</p>\n<p>But then, I thought:</p>\n<p><em>“Ok, this is nice. But when you bet, you don’t bet on a single team, but on the result between the 2 teams that are playing each other.”</em> I.e. if team A has an amazing momentum, and so has team B, the bet will — in theory — be risky.</p>\n<p>Hence, the next step was to address this concern. This was done by checking the momentum score difference between the teams, the bigger the momentum score, the less risky — in theory — a bet would be. What we want to see is a team that has been doing amazing for the past 6 games, and one that has been performing consistently bad.</p>\n<p>Lastly, I added a confidence filter so that the terminal would only output the games that shown at least a certain X confidence. And also, an argument that would select the number of days in the future that we could look for fixtures.</p>\n<p>After having this implemented, the day after was about polishing the code, adding some colouring and emojis, creating a repository for it, a README, discussing the binning of the momentum score and bet confidence terms, creating a logo for it, and creating an executable + adding the logo which my girlfriend did.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"image\" src=\"https://didierlopes.com/assets/images/2021-04-07-momentum-football-bets_1-702956a679d15953cb5e6361cf3b2645.webp\" width=\"388\" height=\"424\" class=\"img_ev3q\"></p>\n<p>After this, we were quite excited to backtest the app. We filtered the next features with a big confidence bet score (to have less risk), and put 20 pounds on 3 different accumulators. <a href=\"https://www.youtube.com/watch?v=-DT7bX-B1Mg\" target=\"_blank\" rel=\"noopener noreferrer\">And it’s gone.</a></p>\n<p>Hope you had a good read. Feedback is always appreciated.</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/momentum-football-bets",
            "title": "Momentum Football Bets",
            "summary": "In this blogpost, I share how I developed an automated task to estimate the momentum of football teams for betting purposes using Beautiful Soup and Python.",
            "date_modified": "2021-04-07T00:00:00.000Z",
            "tags": [
                "football",
                "betting",
                "momentum",
                "web-scraping",
                "beautiful-soup",
                "python"
            ]
        },
        {
            "id": "https://didierlopes.com/blog/gamestonk-terminal-the-next-best-thing-after-bloomberg-terminal",
            "content_html": "<p align=\"center\"><img width=\"600\" src=\"https://didierlopes.com/blog/2021-03-14-gamestonk-terminal-the-next-best-thing-after-bloomberg-terminal_1.webp\"></p>\n<br>\n<p>In this blogpost, I introduce Gamestonk Terminal, an open-source project that aims to be a comprehensive tool for financial analysis and stock market research. It includes functionalities for discovering stocks, market sentiment analysis, fundamental and technical analysis, due diligence, prediction techniques, and more.</p>\n<p>The open source code is available <a href=\"https://github.com/DidierRLopes/GamestonkTerminal\" target=\"_blank\" rel=\"noopener noreferrer\">here</a>.</p>\n<div style=\"border-top:1px solid #0088CC;margin:1.5em 0\"></div>\n<p>If you like stocks and are careful with the way you spend your money, (me saying it seems counter-intuitive given that I bought GME at the peak, I know) you know how much time goes into buying shares of a stock.</p>\n<p>You need to: Find stocks that are somehow undervalued; Research on the company, and its competitors; Check that the financials are healthy; Look into different technical indicators; Investigate SEC fillings and Insider activity; Look up for next earnings date and analysts estimates; Estimate market’s sentiment through Reddit, Twitter, Stocktwits; Read news;. … the list goes on.</p>\n<p>It’s tedious and I don’t have 24k for a Bloomberg terminal. Which led me to the idea during xmas break to spend the time creating my own terminal. I introduce you to “Gamestonk Terminal” (probably should’ve sent 1 tweet everyday to Elon Musk for copyrights permission eheh).</p>\n<p>As someone mentioned, this is meant to be like a swiss army knife for finance.</p>\n<p>It contains the following functionalities:</p>\n<ul>\n<li>\n<p><strong>Discover Stocks</strong>: Some features are: Top gainers; Sectors performance; upcoming earnings releases; top high shorted interest stocks; top stocks with low float; top orders on fidelity; and some SPAC websites with news/calendars.</p>\n</li>\n<li>\n<p><strong>Market Sentiment</strong>: Main features are: Scrolling through Reddit main posts, and most tickers mentions; Extracting trending symbols on stocktwits, or even stocktwit sentiment based on bull/bear flags; Twitter in-depth sentiment prediction using AI; Google mentions over time.</p>\n</li>\n<li>\n<p><strong>Research Web pages</strong>: List of good pages to do research on a stock, e.g. macroaxis, zacks, macrotrends, ..</p>\n</li>\n<li>\n<p><strong>Fundamental Analysis</strong>: Read financials from a company from Market Watch, Yahoo Finance, Alpha Vantage, and Financial Modeling Prep API. Since I only rely on free data, I added the information from all of these, so that the user can get it from the source it trusts the most. Also exports management team behind stock, along with their pages on Google, to speed up research process.</p>\n</li>\n<li>\n<p><strong>Technical Analysis</strong>: The usual technical indicators: sma, rsi, macd, adx, bbands, and more.</p>\n</li>\n<li>\n<p><strong>Due Diligence</strong>: It has several features that I found to be really useful. Some of them are: Latest news of the company; Analyst prices and ratings; Price target from several analysts plot over time vs stock price; Insider activity, and these timestamps marked on the stock price historical data; Latest SEC fillings; Short interest over time; A check for financial warnings based on Sean Seah book.</p>\n</li>\n<li>\n<p><strong>Prediction Techniques</strong>: The one I had more fun with. It tries to predict the stock price, from simple models like sma and arima to complex neural network models, like LSTM. The additional capability here is that all of these are easy to configure. Either through command line arguments, or even in form of a configuration file to define your NN. It also allows backtesting.</p>\n</li>\n<li>\n<p><strong>Reports</strong>: Allows you to run several jobs functionalities and write daily notes on a stock, so that you can assess what you thought about the stock in the past, to perform better decisions.</p>\n</li>\n<li>\n<p><strong>Comparison Analysis</strong>: Allows to compare different stocks.</p>\n</li>\n<li>\n<p><strong>On the ROADMAP</strong>: Cryptocurrencies, Portfolio Analysis, Credit Analysis. Feel free to add the features you’d like and we would happily work on it.</p>\n</li>\n</ul>\n<p>This project will always remain open-source, and the idea is that it can grow substantially over-time so that more and more people start taking advantage of it.</p>\n<p>Feel free to contribute towards the project.</p>\n<p>Feedback is extremely welcome!</p><div style=\"display:flex;justify-content:center;margin-top:3rem;margin-bottom:1rem\"><a href=\"https://substack.com/@didierrlopes\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"mission-button\" style=\"text-decoration:none;white-space:nowrap;padding:12px 24px;font-size:14px\">Subscribe to my newsletter<span style=\"margin-left:6px\">»</span></a></div>",
            "url": "https://didierlopes.com/blog/gamestonk-terminal-the-next-best-thing-after-bloomberg-terminal",
            "title": "Gamestonk Terminal - The next best thing after Bloomberg Terminal",
            "summary": "In this blogpost, I introduce Gamestonk Terminal, an open-source project that aims to be a comprehensive tool for financial analysis and stock market research. It includes functionalities for discovering stocks, market sentiment analysis, fundamental and technical analysis, due diligence, prediction techniques, and more.",
            "date_modified": "2021-03-14T00:00:00.000Z",
            "tags": [
                "gamestonk-terminal",
                "finance",
                "stock-market",
                "programming",
                "open-source"
            ]
        }
    ]
}