Scaling AI for Customer Support at Markprompt with Effect
#2: Scaling AI for Customer Support at Markprompt with Effect
Join us as we talk with Michael Fester from Markprompt about scaling AI-powered customer support with Effect, building reliable and high-performance infrastructure, and enhancing developer productivity in a fast-evolving AI landscape.
Join us as we talk with Michael Fester from Markprompt about scaling AI-powered customer support with Effect, building reliable and high-performance infrastructure, and enhancing developer productivity in a fast-evolving AI landscape.
Effect is an ecosystem of tools to build production-grade software in TypeScript.
Song: Dosi & Aisake - Cruising [NCS Release]
Music provided by NoCopyrightSounds
Free Download/Stream: http://ncs.io/Cruising
Watch: http://ncs.lnk.to/CruisingAT/youtube
- (00:00) - Welcome & guest introduction
- (01:54) - Michael’s journey: from academia to AI & Customer Support
- (03:49) - What is Markprompt? Overview & use cases
- (07:45) - Markprompt’s system architecture
- (10:22) - Challenges of running AI-powered support systems
- (13:20) - Improving reliability with Effect
- (16:41) - Technical architecture breakdown
- (19:51) - The public API server setup
- (23:50) - Ingestion engine
- (26:29) - Onboarding engineers to Effect
- (30:51) - Migrating the codebase to Effect
- (35:19) - Effect in production: the power of schema
- (39:02) - Migrating to Effect: challenges & key takeaways
- (41:45) - Effect brings out the best in us engineers
- (45:34) - The Future of AI infrastructure
- (50:18) - Closing remarks & thanks
Transcript
01:00:00As an engineer, you want to build
01:00:01features, you want to
01:00:01build like real robust systems.
01:00:04You want to spend ideally
01:00:05all your time doing that.
01:00:06You don't want to spend your time
01:00:08fighting the language,
01:00:09building something that, you
01:00:10know, the language was not meant for.
01:00:12To give you an example,
01:00:13like concurrency in TypeScript.
01:00:14You want a way to build a concurrent
01:00:17system where you're
01:00:18thinking about what is
01:00:19the system actually doing rather than
01:00:20like setting up all the
01:00:22boilerplate in order to
01:00:23have that system in place.
01:00:25So I would say Effect really
01:00:27gives you the right premise.
01:00:28So now that we've completed this
01:00:30migration, kind of feel
01:00:31like this is the end game feels
01:00:33like more stable and at least if we
01:00:35continue building our
01:00:36code base on TypeScript with
01:00:38Effect, it doesn't feel like we're going
01:00:39to spend many more like
01:00:41cycles, like refactoring
01:00:43the code.
01:00:47Welcome to Cause & Effect, a podcast
01:00:49about the TypeScript
01:00:50library and ecosystem called
01:00:51Effect, helping engineers to build
01:00:54production-ready software.
01:00:56I'm your host, Johannes Schickling, and I've
01:00:58been building with
01:00:58Effect for over four years.
01:01:00With this podcast, I want to help others
01:01:02understand the powers and
01:01:04benefits of using Effect.
01:01:06In this episode, I'm talking to Michael
01:01:08Fester, co-founder of
01:01:10Markprompt, an AI-based customer
01:01:12support platform.
01:01:13In this conversation, we explore how
01:01:16Markprompt uses Effect
01:01:17across its entire architecture,
01:01:20including API and RPC endpoints,
01:01:22long-running workflows, and their
01:01:24customer-facing product.
01:01:25Let's get into it.
01:01:28Hey, welcome Michael.
01:01:29So nice to have you on the
01:01:30Cause & Effect Podcast.
01:01:31How are you doing?
01:01:32I'm good.
01:01:33Thank you.
01:01:33I'm really happy to be here.
01:01:35It's been, I guess it's been a while that
01:01:36we're trying to
01:01:37organize this, but I'm very
01:01:39happy that we're doing it now.
01:01:41Yeah.
01:01:41I mean, you're super, super busy.
01:01:44You're based in San
01:01:45Francisco building an AI company.
01:01:48So I'm really, really happy that you took
01:01:50the time to share
01:01:51your story about Effect.
01:01:53Maybe you can share a little bit about
01:01:56yourself, your
01:01:56background and what are you doing?
01:01:59Yeah, sure.
01:02:00So I have a background.
01:02:02I started in academia.
01:02:03Actually, I was doing
01:02:04research in mathematics.
01:02:05Then I started getting into AI and I
01:02:07built my first AI
01:02:08company in Europe, specialized
01:02:10on device voice recognition.
01:02:12And we got acquired by Sonos.
01:02:14And since then I moved here to San
01:02:17Francisco for my next
01:02:19venture, which is we're building
01:02:22AI infrastructure for customer support.
01:02:25So this is all like posts,
01:02:27chat GPT, GPT 4 coming out.
01:02:30And we saw this, this incredible
01:02:31opportunity to start
01:02:32working in this space.
01:02:35That is awesome.
01:02:36And I highly encourage everyone who is
01:02:40like interested in AI,
01:02:41particularly is looking
01:02:43for a better customer support solution to
01:02:46check out Markprompt.
01:02:48Can you share about a few companies who
01:02:50are already using Markprompt?
01:02:51Yeah, sure.
01:02:52So we've been working very closely with
01:02:55some companies very
01:02:56early on in the process.
01:02:57Actually, that's really interesting.
01:02:58Vercel started using us as one of our
01:03:00first customers,
01:03:01actually ElevenLabs, Replicate.
01:03:03Things are just moving so fast.
01:03:05So our approach here is not so much of a,
01:03:08you know, we have a
01:03:09vision of how things will
01:03:10end up, right?
01:03:11It's very much like a learning process,
01:03:13working very, very
01:03:14closely with customers, hand in
01:03:16hand getting their feedback,
01:03:17understanding together, how
01:03:19this thing is evolving, how
01:03:21we can improve, you know, the behavior of
01:03:23the LLMs or how we can
01:03:24extend the use cases.
01:03:26So this has been a very different way, I
01:03:28would say, of building
01:03:29a company from the past,
01:03:30because it's so new to
01:03:32everyone in the space.
01:03:33And we're just like scratching the
01:03:35surface of the
01:03:35opportunities of building these systems
01:03:38for you know, down the line.
01:03:40That's awesome.
01:03:41So before we go into the technical parts,
01:03:44maybe you can share
01:03:45through the lens of one
01:03:47of your typical customers, what
01:03:49Markpompt does and which
01:03:51problems it solves for some
01:03:53of those customers.
01:03:54Sure.
01:03:55So there's multiple facets of this
01:03:57running a support
01:03:58operation is it's not a one size
01:04:01fits all.
01:04:02Every company has their own ways of, you
01:04:04know, the nature of
01:04:05customer issues, the way that
01:04:07they engage with customers,
01:04:09is it like direct contact?
01:04:11Is it, you know, is it mostly self serve?
01:04:14Technical challenges are very different
01:04:16from one company to the other.
01:04:18So we offer really an
01:04:20end to end solution.
01:04:21So there's multiple
01:04:23components in our system.
01:04:24It all starts with understanding your
01:04:26system of record, which is
01:04:28things like your underlying
01:04:30customer knowledge, your, you know, your
01:04:33documentation, your CRM, the API is that
01:04:37you use for automating
01:04:39parts of your support.
01:04:41And we connect all that together.
01:04:43And then we build applications that are
01:04:45either customer facing
01:04:46or agent facing so and use
01:04:49internally for the company.
01:04:51So it can be, you know, everything from,
01:04:52you know, your contact form powered by AI
01:04:55to your chatbot to your
01:04:58Slack and Discord bots, right?
01:05:00This is customer
01:05:01facing email order replies.
01:05:04So you send an email and the AI agent
01:05:08will start, you know,
01:05:09trying to resolve the issue
01:05:11for you.
01:05:12And it might be possible
01:05:13that it resolves it fully.
01:05:16And if not, it's going to ask you for all
01:05:17the questions that the team then needs to
01:05:19use once you know, the ticket
01:05:21hits the inbox internally.
01:05:23And then there's the all the features
01:05:25which are internal
01:05:26facing for the support
01:05:28team to be able to streamline their work.
01:05:31Because the truth is that customer
01:05:32support before AI involved
01:05:36a lot of essentially like
01:05:38robotic work, just answering the same
01:05:41questions over and over again.
01:05:42This is not super engaging
01:05:44and exciting just to have
01:05:45to answer the same
01:05:46question over and over again.
01:05:47So if you can start like taking that
01:05:49burden off of your
01:05:50shoulders and help you, you know,
01:05:52work on more like high leverage strategic
01:05:56questions, then, you
01:05:58know, we can really help
01:05:59streamline the support operation.
01:06:00what happens when you've put
01:06:01an AI or both like customer
01:06:03facing and agent facing, then you can
01:06:06start, you know,
01:06:07extracting a lot of intelligence,
01:06:09a lot of knowledge, because you're really
01:06:10at the nerve center
01:06:11in a company, you are,
01:06:13you know, the interface between your
01:06:15customers and your company, right?
01:06:18So you have so much like knowledge that
01:06:20often just gets siloed
01:06:21within the support team,
01:06:23right?
01:06:23It's it's actually very rare that support
01:06:25team reports to product, right?
01:06:28And I think that's a
01:06:29that's really a problem.
01:06:30But if we can start rooting
01:06:32out all this insight and
01:06:33knowledge, we can start
01:06:35having a really, really good
01:06:36understanding on, you know,
01:06:37product shortcomings, where
01:06:39the engineering team might,
01:06:40you know, put some effort, right?
01:06:43Because this is where your customers have
01:06:44been experiencing a
01:06:46lot of friction, right?
01:06:47So we can start generating these
01:06:49reporting and all sorts of
01:06:51other insights that can help
01:06:53you as a company
01:06:54streamline your operations,
01:06:56things like spotting knowledge
01:06:57gaps, right, helping you write, you know,
01:06:59keeping your your
01:07:00documentation up to date,
01:07:02these are all things that
01:07:02we can start also working on.
01:07:05So this concept of
01:07:05agent is very versatile.
01:07:08The agents can solve issues, they can,
01:07:10you know, answer emails,
01:07:11but they can also start
01:07:12being tasked of gathering
01:07:14insights and producing new
01:07:15knowledge and keeping your
01:07:16system of record,
01:07:17always up to date.
01:07:18So there's really a lot of
01:07:19things that need to happen.
01:07:20You cannot approach the
01:07:22problem just from one
01:07:23angle, you really want to tie
01:07:24the whole thing together, because this is
01:07:26where you start creating
01:07:27these positive feedback
01:07:28loops, so called data flywheels, right,
01:07:31that enable you to
01:07:32start deploying the solution
01:07:33and trust it that it's
01:07:34operating really well.
01:07:36So yeah, there's,
01:07:37there's a lot of things to it.
01:07:38That sounds fascinating, and also quite
01:07:41complex in terms of the
01:07:42different surface areas, etc.
01:07:45So maybe we can go
01:07:46slightly more technical.
01:07:47And before we go into all of the Effect's
01:07:49specifics, can you more from like an
01:07:52engineering perspective
01:07:53provide an overview over your system?
01:07:56And which different high level components
01:07:59it's composed out of?
01:08:01Sure.
01:08:02So this is a, you know, apart from the
01:08:04machine learning things,
01:08:06the LLM things, this is a
01:08:08classical, you know, setup.
01:08:09there's some servers, both
01:08:11like short, like serverless instances for
01:08:13API endpoints, then
01:08:14there's some long running
01:08:16servers to do things like, you know, pre
01:08:18processing data, post
01:08:21processing, interactions.
01:08:23So yeah, there's a there's a bunch of
01:08:25servers here, everything
01:08:25is in node, everything is
01:08:27or TypeScript.
01:08:29The front end is a React application.
01:08:32So both we have a dashboard, which is a V
01:08:35duplication, there is
01:08:37some integrations
01:08:38inside of Salesforce,
01:08:39Zendesk, Slack, and so on.
01:08:41So it's a classical full
01:08:43stack, React TypeScript application.
01:08:47So you've built quite an expansive system
01:08:49here and building all
01:08:51of that in TypeScript
01:08:52I think TypeScript is sort of notorious
01:08:54for only scratching the
01:08:55surface and only covering
01:08:57the happy path.
01:08:58There's a lot of things that can go wrong
01:09:00in all of those systems, integrating with
01:09:03different systems.
01:09:04All of those things I think have led you
01:09:06to take a more serious
01:09:08look at Effect and ultimately
01:09:10adopting it.
01:09:11So can you share that journey of going
01:09:14from a non-Effect code
01:09:16base to converting step
01:09:18by step to Effect?
01:09:20Sure, so obviously there's the common
01:09:22complexity increase that
01:09:24happens when you're building
01:09:25a product and putting it into production.
01:09:27So as you add features and so on, then
01:09:29you hit sort of a ceiling
01:09:31and then you start assessing
01:09:33the situation and then you might start
01:09:35refactoring and so on.
01:09:36And then next phase, you hit some other
01:09:39limitations and then you
01:09:41reassess again the situation.
01:09:44So that's just the common thing of
01:09:45working on an
01:09:46increasingly growing code base.
01:09:49But then there's LLMs and these are
01:09:51non-deterministic systems and it poses
01:09:54some completely new kinds
01:09:56of challenges.
01:09:56How do you monitor the behavior of the
01:09:58system, for instance?
01:10:00How do you deal with readable streams
01:10:02instead of just sending over a payload?
01:10:05This has the potential to making your
01:10:07code base more complex
01:10:08if you need to stream some
01:10:10tokens down to the customer, but you
01:10:12actually also need to
01:10:13store these chunks on your own
01:10:16for post-processing.
01:10:17How do you deal with that?
01:10:18TypeScript doesn't give you
01:10:19some great answers to this.
01:10:22How do you deal with reliability?
01:10:24OpenAI and Anthropic and so on, they offer
01:10:27a service which is in high demand.
01:10:31We are in a period right
01:10:33now with scarce resources.
01:10:35So these APIs, they go down and they
01:10:37actually go down more
01:10:38than you would think.
01:10:40And so how do you build fallback
01:10:42mechanisms so that, say that
01:10:44OpenAI is down as your main
01:10:46provider, your customers cannot be down.
01:10:48If OpenAI is down,
01:10:49that's not their problem.
01:10:50That's our problem.
01:10:52So how do you build a
01:10:53fallback system to Anthropic?
01:10:55What happens a few weeks ago when OpenAI
01:10:58was down for, I think,
01:11:00five hours and then the
01:11:01entire industry shifts towards Anthropic
01:11:04that just has this
01:11:05spike that they're unable
01:11:07to deal with?
01:11:08So they are experiencing outage or just
01:11:11very degraded performance.
01:11:13There's outage and then there's actually
01:11:15performance, the
01:11:16speed of tokens and so on.
01:11:19All that, there's no good answer, no
01:11:22clear best practice in
01:11:25vanilla TypeScript to deal
01:11:27with these things.
01:11:28And then there's the fact that we are a
01:11:29startup working in a
01:11:31fast-paced environment where
01:11:33things change all the time.
01:11:36And we want to be efficient and we want
01:11:37to be able to not deal
01:11:39with all the complexity
01:11:41and all the problems and down times and
01:11:42reliability, but we need to
01:11:44be effective in shipping new
01:11:46features to constantly
01:11:47meet up with the demand.
01:11:49the zero to one of
01:11:50building a company here.
01:11:51So there's multiple factors that really
01:11:54made us think hard about
01:11:55what would be the foundation
01:11:58for us to be able to operate really fast
01:12:00with a small set of
01:12:02resources from a startup and
01:12:04be a highly reliable solution because we
01:12:07are catering to larger
01:12:08companies, enterprise
01:12:10companies.
01:12:10So reliability is just really key.
01:12:13Obviously, I can talk a lot about the
01:12:15whole telemetry part of
01:12:18things, making sure everything
01:12:20is properly monitored and that we can
01:12:21actually spot when things
01:12:24go wrong before our customers
01:12:25even see it and then we can take action.
01:12:28So there's a bunch of things here.
01:12:29And Effect just came at a very good
01:12:31moment where we still had
01:12:33a sufficiently small code
01:12:36base that we could actually start
01:12:38seriously thinking about
01:12:39completely converting it to
01:12:40Effect.
01:12:41So the timing was really good.
01:12:43So you've mentioned in regards to
01:12:45adopting Effect for the
01:12:46sake of improving reliability,
01:12:49one specific use case was that Markbrom
01:12:52is using LLMs such as
01:12:54the products provided by
01:12:56OpenAI.
01:12:56And if they go down, you need to fall
01:12:58back to another system.
01:13:00And in case that system also goes down,
01:13:02fall back to yet another one.
01:13:04All of that is helping to improve the
01:13:07reliability of Markprompt.
01:13:10Which other challenges did you face
01:13:12similar to that one in
01:13:14regards to reliability and
01:13:15how did you improve
01:13:16reliability through Effect?
01:13:19I mean, there's lots of examples where
01:13:21Effect has helped us
01:13:23consolidate our system.
01:13:25One example is one day we woke up and we
01:13:28realized that we were under
01:13:29attack by a malicious hacker
01:13:32who was interacting with a public facing
01:13:35deployment of Markprompt and
01:13:37sending, I think, 20 million
01:13:40requests per hour.
01:13:43And this was across the globe, so it was
01:13:46kind of hard to deal with.
01:13:47So Ethan Niser, he spent the summer with
01:13:50us and he's been working
01:13:53on a lot of Effect-related
01:13:54things and on his first day,
01:13:56this attack started happening.
01:13:58And so he built this great rate limiting
01:14:02system in the middleware
01:14:03that is capable of looking
01:14:04at multiple facets of a payload.
01:14:08And the interesting thing here is that
01:14:09you cannot just rely
01:14:11on IP and fingerprinting
01:14:12and so on.
01:14:13You actually also want to start looking
01:14:14at the LLM payload itself.
01:14:16What kinds of messages is there, pattern
01:14:18that we can spot here in
01:14:20the nature of the requests?
01:14:22And so it's a multi-tiered rate limiting
01:14:24system that is very easy
01:14:25to automatically trigger
01:14:27and also manually trigger.
01:14:28So this is an example also where building
01:14:30with composability has just allowed us to
01:14:34build a fairly sophisticated
01:14:35system here, which just works.
01:14:38We are now very
01:14:39confident that it just works.
01:14:40And by the way, one of the reasons that
01:14:42we're confident that it
01:14:43works is that it's very
01:14:44easy to test because the whole dependency
01:14:46injection story is
01:14:47just such a natural thing
01:14:48to do.
01:14:49You just operate a provider and you can
01:14:51very easily simulate a
01:14:53situation that is hard to
01:14:55reproduce with other means.
01:14:56So dependency injection, I would say, is
01:14:59a huge factor to the
01:15:00reliability because we
01:15:01can restart testing all sorts of
01:15:05different combinations of
01:15:06non-happy paths and building
01:15:08that with just change or service that you
01:15:12provide is just very,
01:15:13very easy with Effect.
01:15:14Telemetry is obviously a thing.
01:15:16So I think that the whole testing story
01:15:19is not just about one thing.
01:15:22You want to do unit tests.
01:15:23You want to do integration tests with
01:15:25dependency injection.
01:15:26You also really want to have a full
01:15:28understanding of what's going
01:15:29on when you are in production.
01:15:31And so being able to have good traces,
01:15:33good logging of every
01:15:35component of your system
01:15:36is non-trivial.
01:15:38And so we rely heavily on telemetry and
01:15:41Effect allows us to just
01:15:43add spans everywhere in
01:15:45a very, very simple way.
01:15:46And it just naturally fits
01:15:48into the rest of the system.
01:15:50And this really has allowed us to have a
01:15:51very, very good
01:15:52understanding of failure scenarios
01:15:55before our customers even see them.
01:15:57So these are just general patterns that
01:15:59are very natural to do
01:16:01in Effect that we don't
01:16:02even think about because they actually
01:16:05don't incur any sort of
01:16:07additional thinking on our
01:16:08part.
01:16:09It's just adding a line
01:16:11and then it just works.
01:16:12Yeah, this makes a lot of sense.
01:16:14I can totally see how reliability is
01:16:17almost sort of like a emerging factor,
01:16:20like a second order effect that comes
01:16:22when you have a composable system,
01:16:25and when you have observability, when you
01:16:28can look into what's going on,
01:16:30when you can eat your
01:16:32vegetables, then you're healthy.
01:16:34And so
01:16:35Building a reliable system is going the
01:16:37extra mile on all of those things.
01:16:39This makes a lot of sense.
01:16:41Given that you built
01:16:42quite an expansive system,
01:16:44maybe we can try to break it down a
01:16:46little bit more with a technical lens on.
01:16:49So I'm sure that you have
01:16:51a client side application.
01:16:53You've mentioned that it's like a single
01:16:54page app built with Vite,
01:16:57but more on the backend side.
01:16:59Can you describe to me what are the
01:17:02different subcomponents of your system?
01:17:04Yeah, so in a very simple way, the main
01:17:07subcomponents here,
01:17:09there's the application server,
01:17:11which is essentially an RPC
01:17:12server that the client
01:17:14application is speaking with.
01:17:15Then we have a public API.
01:17:18So Markprompt is built as
01:17:19Stripe for customer support,
01:17:21in the sense that every part of the
01:17:23system can be
01:17:24interacted with via our APIs
01:17:26so that you can actually build deeper
01:17:28product experiences
01:17:29inside of your core product.
01:17:32So we have a public facing API server.
01:17:34Then we have the ingestion engine, which
01:17:37takes in all your systems data.
01:17:40So this can be public facing like a
01:17:41website that we would
01:17:42scrape on a regular basis.
01:17:44It could be GitHub repository or
01:17:47historical tickets from
01:17:49Zendesk and Jira and Confluence
01:17:51and databases from
01:17:53Salesforce and whatnot.
01:17:55So we do a bunch of things here.
01:17:57We import data.
01:17:58We chunk it up.
01:17:58We monitor the whole structure of
01:18:02documents through the AST
01:18:03and then we build
01:18:04embeddings for multi-levels.
01:18:06And then we store them
01:18:07in a vector database.
01:18:08And then we have all the
01:18:09application related servers,
01:18:11so things like Discord or
01:18:13Slack or Zendesk and so on,
01:18:15which are more like simple servers here.
01:18:18Got it.
01:18:18Yeah, that makes a lot of sense to break
01:18:20it up into those different pieces.
01:18:22I'd actually love to learn a
01:18:24little bit more about each,
01:18:25maybe starting with
01:18:26the application server.
01:18:28So you mentioned that you're
01:18:29using Effect RPC in that regard.
01:18:31What did you use before
01:18:33you were using Effect?
01:18:34And what are the qualities of using
01:18:37Effect for an
01:18:39application for an RPC server here?
01:18:41Yeah, sure.
01:18:43I mean, this before was
01:18:44just like simple API handlers.
01:18:46So you would have two
01:18:48completely decoupled systems.
01:18:51And now pretty much all the
01:18:53endpoints are in full RPC.
01:18:56It starts with a schema, actually.
01:18:58We define the input schema, the output
01:19:01schema, and the error schema
01:19:03for each of these endpoints.
01:19:05And then it trickles down all the way to
01:19:07the client application.
01:19:08So we have this.
01:19:09Ethan actually wrote this and I hope he's
01:19:10going to publish it.
01:19:11Sometimes soon, essentially React query,
01:19:13but wrapped around with Effect
01:19:15so that we have the full schema from the
01:19:17backend all the way to
01:19:18the client side code.
01:19:19And we have nothing more to deal with.
01:19:21So the whole thing is completely
01:19:22streamlined in terms of the
01:19:24communication between the client
01:19:26and the server.
01:19:28That makes a lot of sense.
01:19:29And so before you
01:19:30didn't have any schema layer,
01:19:32anything to express the kind of data
01:19:35you're sending across?
01:19:37No, we didn't actually.
01:19:39Got it.
01:19:39Well, I suppose that through the process
01:19:42of just modeling the schema,
01:19:44I'm sure that there were a couple of code
01:19:46paths that you didn't
01:19:47even account for before.
01:19:49So the--
01:19:50Absolutely.
01:19:51The public API server where you're
01:19:55exposing an open API spec, I suppose,
01:19:59how similar or different is that to
01:20:01your application server?
01:20:02Can you describe the public
01:20:03API server setup a bit more?
01:20:06Yeah, sure.
01:20:06So this is more of a
01:20:08standard HTTP server.
01:20:10This is actually using Effect HTTP.
01:20:12So again, we have the full--
01:20:13Everything starts with the Effect runtime
01:20:17taking over directly
01:20:18at the request level.
01:20:19So again, we can model
01:20:20everything very nicely via schemas.
01:20:23And one really nice thing of having
01:20:26everything defined by schemas is
01:20:28that we can, for instance, automatically
01:20:30generate the open API spec.
01:20:32So this is something that we now have
01:20:34every single endpoint is
01:20:35automatically documented
01:20:37just via the schema.
01:20:39Got it.
01:20:39How much overlap does your
01:20:41internal application server,
01:20:43that RPC server with
01:20:45the public API server,
01:20:47does it have a lot of overlap?
01:20:49Do you reuse a lot of code internally?
01:20:51Or are those rather
01:20:52fulfilling different purposes?
01:20:54They're fulfilling
01:20:55completely different purposes, yes.
01:20:58So yeah, I mean, these things are
01:21:00completely separate.
01:21:02So to give you one very important
01:21:04differentiator is that on the RPC server,
01:21:07we provide permissions.
01:21:10So you want to make sure that a given
01:21:12user can perform an action
01:21:14that they are allowed to.
01:21:16And so we have a very nice system that
01:21:19provides the level of
01:21:21permissions of a user.
01:21:23This is completely transparent.
01:21:25We actually used RLS before,
01:21:28role level security to
01:21:29enforce these policies.
01:21:31But there was a real performance impact.
01:21:33It was just slowing down the crazy,
01:21:34especially when you're dealing with
01:21:36hundreds of thousands of data points.
01:21:39So this had a real impact.
01:21:41So we got rid of that.
01:21:42And actually, everything
01:21:43now is modeled in code.
01:21:44So the permission, which I guess was
01:21:46always how things have
01:21:48been done without RLS.
01:21:52And so this is, again, an example where
01:21:54Effect at the type level,
01:21:56you can immediately spot whether this is
01:21:58a user that is allowed to
01:22:00perform a single action,
01:22:02because that service
01:22:04requires these sets of permissions.
01:22:06And so this is very,
01:22:07very nice to model as well.
01:22:09That sounds very interesting.
01:22:10So you've built yourself an internal DSL
01:22:13to model those permission rules.
01:22:16Can you explain a little bit more how
01:22:18that's implemented and how
01:22:20that can be imagined from
01:22:22like a type level
01:22:23perspective or from an API perspective?
01:22:26Yeah.
01:22:27I mean, so every user comes
01:22:28with a set of permissions, right?
01:22:30And these permissions
01:22:30can be modeled via types.
01:22:33And services can declare what level of
01:22:38permission they required in
01:22:40order to perform an action.
01:22:42And so we immediately know if within an
01:22:45RPC endpoint, we're using a service,
01:22:47but that the provided
01:22:48permissions don't match.
01:22:52Well, then we can flag it.
01:22:53And so we can guarantee that there's no
01:22:55code being shipped where
01:22:56there's an inconsistency here.
01:22:59I love it.
01:22:59That sounds very elegant.
01:23:00I would love to see some code for that.
01:23:03Could you imagine that there could be a
01:23:05more commonly reusable package for that?
01:23:08Or is that only something that makes
01:23:10sense within your code base?
01:23:13Good question.
01:23:15Obviously, we have been just crunching
01:23:18through this code and
01:23:19getting into production.
01:23:20So we haven't thought too much about how
01:23:23this would extend to a
01:23:24more generic use case.
01:23:27But I guess this could be
01:23:29a very interesting topic.
01:23:31Right.
01:23:31Well, anyone in the audience is happily
01:23:34invited to try to
01:23:35replicate this by themselves.
01:23:37Maybe that's even something that we
01:23:39could, as part of the Effect org, also
01:23:42look into providing.
01:23:43To hear you describing
01:23:44this use case in this DSL,
01:23:46that makes a lot of
01:23:47sense for a lot of use cases.
01:23:49So moving then to the ingestion engine,
01:23:53can you describe a little bit more of how
01:23:56that looks like from a
01:23:57lifecycle perspective?
01:23:59So you've mentioned the ingestion engine
01:24:01is mostly meant to bring in data from
01:24:03various data sources,
01:24:05whether it's
01:24:05Salesforce, whether it's Notion.
01:24:07Walk me through how that works and how
01:24:10does that work in regards to Effect?
01:24:13Do you use Effect streams for that?
01:24:15Yeah.
01:24:15How does that work?
01:24:17So it's still pretty bare bones here.
01:24:19This is something that we have been
01:24:20discussing also with the
01:24:21Effect team and the Effect cluster.
01:24:23This is where we will probably be going.
01:24:26So now we have our own system, which is
01:24:28basically just some
01:24:31long running node servers
01:24:32that are able to go and fetch the data.
01:24:36So that could be make a large request to
01:24:39an SQL database or starting a scraper
01:24:42that visits a website and when it's done
01:24:45and purged all the pages,
01:24:48it is then indexed in a
01:24:49temporary cache on our side.
01:24:52And then it goes into the post processing
01:24:53pipeline, where again, we obviously we
01:24:56parallelize all this
01:24:58because every page
01:24:59needs some post processing.
01:25:01So we chunk it up and we try to get a
01:25:05sense of the structure
01:25:06of the document, the AST,
01:25:08and then we build these embeddings for
01:25:10each levels in the AST and
01:25:12then we store it in a database.
01:25:15And so the main challenge here is that
01:25:17these are long running
01:25:18tasks which can time out,
01:25:20they can fail and whatnot.
01:25:24And so now we rely on external systems to
01:25:26do the whole workflow orchestration,
01:25:28but this is something where we are going
01:25:30to be investing some
01:25:30effort as well because
01:25:32Effect is the perfect solution here
01:25:35because we have the full
01:25:37sets of tools for dealing with
01:25:40these kinds of situations.
01:25:42Yeah, I'm really looking forward for
01:25:45Effect Cluster and Effect
01:25:46Workflows to mature further.
01:25:49I think there's more and more use cases,
01:25:52particularly when it
01:25:53comes to AI applications
01:25:55where you want to express
01:25:56things as long running workflows.
01:25:59And I think this is where Effect is
01:26:02really like such a perfect foundation.
01:26:05So yeah, I think we're going to see some
01:26:08very interesting updates
01:26:09throughout the year here.
01:26:11So stay tuned for that.
01:26:13Maybe changing gears slightly.
01:26:15Initially, you've built all of the
01:26:17system, I think mostly by yourself.
01:26:19This is where you started
01:26:21adopting Effect by yourself.
01:26:23and then later you onboarded other
01:26:25engineers who didn't have
01:26:27prior Effect experience.
01:26:29Can you share a bit more about that
01:26:31story, how you onboarded
01:26:33other engineers who didn't
01:26:34have Effect experience to become
01:26:36successful working on your code base?
01:26:39I mean, this is such
01:26:39an interesting question.
01:26:40Because you would think that Effect is
01:26:44mainly for a TypeScript audience.
01:26:47Web developers who are proficient now in
01:26:50TypeScript and realize they
01:26:52need to go to the next level
01:26:54in terms of building complex systems.
01:26:56My take here is actually that having a
01:27:00code base which is already
01:27:01fully Effect will actually
01:27:04lower the barrier to entry for people who
01:27:07have less experience with TypeScript.
01:27:10So we've seen that with Elliot, our
01:27:13founding engineer who has
01:27:14joined a few months ago,
01:27:15with very little TypeScript experience,
01:27:17was able to very quickly take
01:27:20it up and then be productive.
01:27:22We've run some trials with some
01:27:23candidates in the last few weeks with,
01:27:26again, little experience in
01:27:27TypeScript.
01:27:28The thing is that we are hiring a lot of
01:27:30machine learning engineers.
01:27:32And so they have typically already a lot
01:27:35of experience with more
01:27:36of the machine learning
01:27:37sets of tools like Python
01:27:39and very little on TypeScript.
01:27:41But what we have seen is onboarding them
01:27:44on our code base, they
01:27:45were actually able to be
01:27:46very productive, very early on.
01:27:48And the great thing is that there's not
01:27:50much room for bad
01:27:51practice or the kinds of things
01:27:53that you need to learn when you get
01:27:55started with a new language.
01:27:56So what I think is that actually
01:27:58Effect will
01:27:59allow them to be proficient and
01:28:02build very reliable
01:28:03code within a few weeks.
01:28:05If it had not been an Effect and more
01:28:07like vanilla TypeScript,
01:28:08yes, sure, there's fewer
01:28:09things to learn.
01:28:10It's kind of easy and so on.
01:28:12But you would build up this understanding
01:28:15and intuition for the
01:28:16language over the course of
01:28:17years.
01:28:18Right.
01:28:18And then within years, you'll be able to
01:28:19build very complex and
01:28:21reliable systems because you
01:28:23have been proficient in the language.
01:28:26So Effect gives you these guardrails that
01:28:29with the whole thing is
01:28:31in Effect, sure, you need
01:28:32to understand the
01:28:33whole catalog of things.
01:28:35And this you just take up
01:28:36as you have new use cases.
01:28:37But if you have a really good foundation,
01:28:39like the full RPC
01:28:41server, you basically just
01:28:43you start writing schema, right?
01:28:45You write a schema and then
01:28:46you fit it into the system.
01:28:48And then once it's there, it's done.
01:28:51You don't need to change it.
01:28:52You haven't done anything bad
01:28:54or anything that will break.
01:28:56Right.
01:28:56So my take on this is that actually it
01:28:59might actually have the
01:29:00opposite effect of what
01:29:01we would expect, which is to be able to
01:29:03onboard non TypeScript
01:29:06engineers much, much faster.
01:29:09Yeah, that definitely sounds
01:29:11a little bit counterintuitive.
01:29:12And the first time I heard about this
01:29:15anecdote, and you shared
01:29:16this privately with me before,
01:29:18and that person you've just mentioned,
01:29:21Elliot, gave a brilliant talk at the last
01:29:23Effect Meetup in San Francisco where he
01:29:26shared his first hand
01:29:28experience learning Effect.
01:29:30And yeah, I think that is a
01:29:32little bit counterintuitive.
01:29:33But when you think about it more, it
01:29:35makes a lot of sense because most
01:29:37experienced TypeScript
01:29:39engineers over years, they had to first
01:29:42learn how to do anything
01:29:44with TypeScript at all and then
01:29:46later learn to ignore like those 80 paths
01:29:49out of 100 how you could do
01:29:52something with TypeScript,
01:29:53but that will lead you
01:29:54down a dangerous road.
01:29:56Whereas Effect constrains you a little
01:29:58bit more and puts you on a
01:30:01path to success in a way.
01:30:03That's also like it has been my
01:30:04experience for I think for me
01:30:06coming more from TypeScript,
01:30:09I had to unlearn a lot of things how I
01:30:12used to do things in TypeScript before.
01:30:14But this is where for me, a good
01:30:17foundation to pick up Effect
01:30:19was actually dabbling in other
01:30:21languages such as Swift and Rust, where I
01:30:24already primed my mind more on more saner
01:30:29engineering practices and learning the
01:30:31right habits and
01:30:33embracing the right abstractions.
01:30:35And so I can totally see how someone who
01:30:38doesn't have prior TypeScript experience
01:30:40maybe experience in other languages,
01:30:42which have more appropriate primitives
01:30:45can be up and running with Effect in no
01:30:48time. That is amazing to hear.
01:30:50So can you walk me through a little bit
01:30:53more through the process
01:30:54how you went tactically
01:30:56about migrating the code base as it was
01:31:00before Effect one by one
01:31:02step at a time to migrating
01:31:03it to Effect. Rome wasn't conquered in a
01:31:06day, so wasn't your code
01:31:08base. So how did you go about it?
01:31:10We had some great help. And this is where
01:31:12I think the Effect community
01:31:13is such a wonderful community
01:31:15of people who are nice and helpful. You
01:31:19kicked it off with us. So we've been
01:31:22this for years. And immediately I saw the
01:31:25importance of this, but
01:31:27never found the time to
01:31:30actually learn how to do it in practice.
01:31:32I think this is also
01:31:33maybe related to the lack of
01:31:34documentation and concrete examples back
01:31:36in the day. How do you
01:31:37actually convert an API
01:31:38endpoint to Effect? How do you just do
01:31:41it? So I think this little
01:31:43catalyzer was really important,
01:31:45which allowed us, our team, to then get a
01:31:49sense of where we could
01:31:50start fitting it in. It was still
01:31:52like very, very new. This was earlier
01:31:53last year. And then we had the pleasure
01:31:57of having Ethan with
01:31:59us over the summer. And he wrote a lot of
01:32:01very important code for both
01:32:03the backend side of things,
01:32:05schema, the database, the React query
01:32:08part, which put us in a
01:32:10really good foundation.
01:32:11We had most of it basically sketched out.
01:32:14And then in September, we decided to
01:32:18do a big, big push and just get
01:32:20everything migrated. So this was like a
01:32:23bit slow in the beginning.
01:32:24And then very, very quickly, within a few
01:32:27weeks, we had the
01:32:28whole thing migrated over.
01:32:32Good. That makes a lot of sense. And
01:32:34happy to have acted as
01:32:36a little catalyst here,
01:32:38but you've picked up everything so
01:32:40quickly. So I think this was rather a
01:32:43little bit of giving you
01:32:45more courage to go this way. And I think
01:32:48you figured out quickly
01:32:50how to work with everything,
01:32:53and you migrated everything in no time. I
01:32:57would say, honestly,
01:32:59the important thing is the
01:33:00catalyzer here. Once you have the starter
01:33:03blocks, then it's quite easy to
01:33:05generalize. It's more
01:33:07like where do you start? And the
01:33:09documentation obviously is much better
01:33:10now. So I think this is
01:33:11a great thing. But I think this little
01:33:14initial nudge is
01:33:17what made the difference here.
01:33:19If you think about your system as sort of
01:33:22like a tree of different subsystems,
01:33:27you can go about converting an existing
01:33:29system to Effect in different ways.
01:33:31Either you go first for
01:33:33the leaves, and then you go up one step
01:33:36at a time until your entire
01:33:37program, your entire system is
01:33:39refactored with Effect. But you can also
01:33:41isolate specific sub nodes
01:33:44and from the outside call the
01:33:47effect and inside of it call other
01:33:50things that are not yet Effect with
01:33:52Effect.runPromise or
01:33:54effect dot promise to run some effects,
01:33:57some non-effect code yet.
01:34:00Did you find any particular
01:34:02topology adoption strategy for you to be
01:34:06working well? So did you go first
01:34:08all for the leaves? Or did you go
01:34:11wherever you wanted to
01:34:12refactor something anyway? How did you
01:34:14go about the decision process of when to
01:34:17refactor what with Effect?
01:34:19Well, yeah, it was the leaves in
01:34:20the beginning. And then it was the top
01:34:24down afterwards, because
01:34:26we just realized that this
01:34:27was what we needed. And we just needed as
01:34:29quickly as possible. So
01:34:31then there was a combined push
01:34:34from the whole team to just get the
01:34:36migration done as quickly as
01:34:37possible. So the RPC was written
01:34:40really like top down, right? Because,
01:34:43well top down in the
01:34:44sense that one route would be
01:34:47migrated to RPC, Effect RPC, then another
01:34:49one and so on. But for
01:34:52sure, this is a nice thing with
01:34:53Effect is that you can do it on the
01:34:55leave to start with and you're not
01:34:57touching anything else
01:34:58of your code base. But yeah, you
01:35:00definitely feel the urge to
01:35:01get the whole thing end to end.
01:35:05The runtime should be initiated at the
01:35:08very beginning of the
01:35:10thing, right? So that you have
01:35:11the full happy path, because you get to
01:35:14love the happy path here, right?
01:35:16Nice. So if I remember
01:35:18correctly, I think it's now been pretty
01:35:20much a year since you've been using
01:35:22Effect in production.
01:35:24looking back, what were some
01:35:26of the things that were
01:35:27like unexpectedly good with
01:35:30Effect and also some things that were
01:35:32more challenging that you thought or
01:35:33unexpected in some ways?
01:35:36I didn't expect the Schema package
01:35:39to be, you know, I didn't have any
01:35:42expectations that this
01:35:43was really a core thing. In fact, because
01:35:45this is really wonderful, how you can
01:35:49control both like the
01:35:50decoding part, the encoding part, how you
01:35:53can pipe everything
01:35:54together. This is one of the sort of,
01:36:00it shifts away how you think about a
01:36:01problem. Because usually,
01:36:03now when I think of a problem,
01:36:05I start thinking about what is the
01:36:06schema, right? It is very
01:36:07different from what is the actual
01:36:09application code. You redesign your
01:36:11schema, you think, well, how should it
01:36:13transform the data here?
01:36:16And then you work your way up to getting
01:36:18it all the way in your
01:36:21code. So I think that schema was
01:36:23a very, very positive,
01:36:24unexpected thing that came out of this.
01:36:27To give you an example,
01:36:29I always wanted to, again, in the quest
01:36:32for extreme lining and being
01:36:34as efficient as possible as a
01:36:36startup, things like documentation, I
01:36:39care a lot about documentation. And the
01:36:41more we can put that
01:36:42on like autopilot, the better, right? So
01:36:44the ability to take
01:36:46your public API endpoints,
01:36:47and the other schemas generate an open
01:36:49API spec is exactly the kind of things
01:36:52that you want, right?
01:36:54So this was a very, very nice discovery.
01:36:57Right. That makes a lot of
01:36:59sense. And I think that goes
01:37:00hand in hand with what I've also found in
01:37:04my development practices over the years,
01:37:06is that I always started to think more
01:37:10about the types of a system.
01:37:13That's like typically what I
01:37:13start out with. I just like described the
01:37:16types. But then I've also
01:37:18found myself thinking about,
01:37:20actually, this data of this particular
01:37:22type doesn't just live inside of this
01:37:25boundary of the system,
01:37:26but it needs to move across network
01:37:29boundaries, across threat boundaries,
01:37:31etc. And now you're,
01:37:33you need to serialize, deserialize that
01:37:35variable. And this is where
01:37:38schemas come in. So I ended up
01:37:40doing exactly the same as you. Like I
01:37:43start thinking about like,
01:37:44okay, what data am I dealing
01:37:46with here? And I modeled it as schemas
01:37:49and derived the types from it.
01:37:51And well, we see this here as
01:37:53like a big revelation turns out in other
01:37:56programming languages, that's what you
01:37:58always do. When you have
01:37:59like in Rust, etc. When you have like a
01:38:02struct definition, you can
01:38:03derive schemas from it. But
01:38:06I think for TypeScript, this is really
01:38:08for most engineers, that's
01:38:10something novel. And I think
01:38:12this is a pattern that should be embraced
01:38:14much more since I think
01:38:16default is you just ignore
01:38:18the existence of a schema and you JSON
01:38:21stringify everything. And then you're
01:38:23surprised what happens
01:38:25to your classes or to your dates. So
01:38:27yeah, that schema is such
01:38:29an integral part of Effect,
01:38:32I think is no coincidence. And I'm very
01:38:34happy that it gets so
01:38:36much attention for detail.
01:38:38Yeah, I mean, I would say it's not only
01:38:41the fact that you have like
01:38:42decoding and encoding and so
01:38:44on, it's the fact that it's so much in
01:38:48harmony with the rest of
01:38:49the whole like Effect way of
01:38:51doing things, right? So it just feels so,
01:38:55you know, an integral
01:38:57part of effect itself.
01:38:59Yeah, I fully agree. So in regards to the
01:39:04more challenging aspects,
01:39:06what were some of the challenges that you
01:39:08found working in an Effect code base?
01:39:11Sure. I would say it can give you a sense
01:39:14of, you know
01:39:17maybe a
01:39:17false sense of security.
01:39:19Because you think that everything
01:39:20is dealt with at the
01:39:21type level and you get no
01:39:23flagged of compile time errors and so on.
01:39:26And this is partly
01:39:28true. But I think it's very,
01:39:30very important. It's very important to
01:39:33understand that this is not
01:39:34the case. And it gives you
01:39:36really good like foundation, but you're
01:39:39not exempt of or die or catch all that
01:39:44was put at the end of
01:39:46your pipes. And so all the other errors
01:39:48in between are, you know, just you don't
01:39:52see them. And we had
01:39:52an example where we had this
01:39:55bug in our code base, and it
01:39:56was quite hard to figure out
01:39:59where it went wrong. So I think this is
01:40:01something that, you know,
01:40:02Effect is a very, very powerful
01:40:03tool. And it brings out the best in us,
01:40:08you know, engineers, I think.
01:40:10But it also needs to be
01:40:12dealt with knowing that, you know,
01:40:15it's not like a safety guard
01:40:17or anything, you can mess up
01:40:19and you can do things that are very hard
01:40:21to then investigate because
01:40:23you've built up this, this
01:40:24sense of everything is just working
01:40:26smoothly. So this is one thing I think
01:40:28that this is as important
01:40:30to keep in mind when you're building, you
01:40:32know, on top of Effect. I
01:40:34think another thing that it gets,
01:40:35a little bit hard to track is,
01:40:38dependency
01:40:39injection is just wonderful,
01:40:42in Effect. And I think that's, that's, I
01:40:43would mention this probably
01:40:44as the second most important,
01:40:46discovery or delight of
01:40:48working with Effect. But,
01:40:50you know, where do you put your
01:40:53dependency? Where is it in your code? How
01:40:55do you like chase the
01:40:56dependency, you know, the service
01:40:58that you provided, that is now affecting
01:41:01a completely different
01:41:02part of your code base,
01:41:03that might be, you
01:41:05know, some some tooling
01:41:06to build inside of the
01:41:07IDE itself, to be able to make it easy to
01:41:10spot the connection, right.
01:41:12But now we still like in this
01:41:13very barebone situation where it's kind
01:41:15of hard to understand
01:41:17exactly, you know, the hierarchy of
01:41:20your dependencies, right, and where they
01:41:23are actually being used
01:41:24in your code. So it can be
01:41:26a little bit hard to navigate sometimes.
01:41:28Right. Yeah, I found that
01:41:29myself as well in the project
01:41:31I'm working on. And it is actually
01:41:34something that we're thinking
01:41:35about, that we could possibly
01:41:37enhance through a IDE integration, etc.
01:41:41So stay, stay tuned for
01:41:44for that. You said something
01:41:46interesting just before, where you said
01:41:48effect brings out the
01:41:50best in us engineers. Can you
01:41:53elaborate on that? What do you mean by that
01:41:55Well, as an engineer,
01:41:58you want to build features,
01:41:59you want to build like real robust
01:42:00systems, you want to spend
01:42:03ideally all your time doing
01:42:05that. You don't want to spend your time
01:42:08fighting the language, fighting, you
01:42:10know, building something
01:42:11that you know, the language was not meant
01:42:13for, to give you an
01:42:14example, like concurrency and
01:42:15TypeScript, right, these are things that
01:42:17you know, you want a way to,
01:42:21you know, build a concurrent
01:42:22system, where you're thinking about what
01:42:25is the system actually doing
01:42:26rather than like setting up
01:42:28all the boilerplate in order to have that
01:42:30system in place. So I would
01:42:34say Effect really gives you
01:42:36the right premise. So one thing I'm
01:42:40thinking about is, now that we've
01:42:42completed this migration,
01:42:44the full migration, it kind of feels like
01:42:46this is the end game. I know
01:42:48this might sound a bit like
01:42:50naive or unrealistic, but it kind of
01:42:54feels like more stable.
01:42:56And at least if we continue
01:42:58building our code base on TypeScript with
01:43:00Effect, it doesn't feel
01:43:02like we're going to spend
01:43:04many more like cycles, like refactoring
01:43:06the code, right, it feels
01:43:09like this sort of timeless,
01:43:12like code base now now now it's, it's,
01:43:14it's there. Effect is
01:43:16going to evolve, our code base is
01:43:17going to evolve. It feels like this is
01:43:19going to be like adjustments
01:43:20and not like a full rewrite.
01:43:22And this is what I mean by, you know, it
01:43:24feels like kind of like
01:43:25building a house with some really
01:43:27good like walls and floor and ceiling and
01:43:29so on. It's just there now.
01:43:32And this is what we are all
01:43:34I guess, striving for as engineers is to
01:43:36have these, you know, the
01:43:38right tools, right, the right
01:43:39foundations, instead of having to fight,
01:43:42you know, all these like small things
01:43:44that degrade over time,
01:43:46and then need to revisit them. And you
01:43:48realize how silly you were
01:43:51writing this code, you know,
01:43:52last year kind of thing, it feels like
01:43:54more harmonious and stable
01:43:57Right. I love that. And
01:43:59I think that is also something that has
01:44:02really brought me to Effect.
01:44:04And to flip it on its head,
01:44:06something that I experienced so many
01:44:10times and have observed so many other
01:44:13teams as sort of like a
01:44:15malfunction of engineering teams and of
01:44:18projects that engineers are
01:44:20afraid to make changes in a
01:44:22project. And I've seen this time and time
01:44:25and time again. And when
01:44:27you're afraid to make changes to a
01:44:29project, particularly if the code was
01:44:31written by someone else, maybe
01:44:32the person is no longer there.
01:44:35That's terrible. Like if you're, if
01:44:36you're afraid to change something, you
01:44:38might not change it and
01:44:39you might not improve it. Or if you
01:44:41change it, you don't know
01:44:42about the consequences, etc.
01:44:45And effect allows you to, gives you the
01:44:48confidence to change something and you
01:44:51know what's going to
01:44:52happen. It even makes it fun to do so.
01:44:54And I think that's
01:44:55sort of like a twin to the
01:45:00aspect of composability, almost like the
01:45:03other side of the same
01:45:04coin, where if you can compose
01:45:07things together, you can decompose things
01:45:10that makes, that's, those
01:45:11are just aspects of changing
01:45:13something and changing not in a big bang
01:45:17way, but just moving things
01:45:19around almost feels like a,
01:45:21like a dance. We're getting a little bit
01:45:23too, too like pie in the sky
01:45:26here, but that's really like
01:45:27my reality as well, like working with
01:45:29Effect and one of the things
01:45:31that I like so much about it.
01:45:33And another thing here may be looking a
01:45:35little bit more into the
01:45:36future, but we're increasingly
01:45:37living in the future where we get, where
01:45:40we do a lot of our code
01:45:42development in an AI-assisted way.
01:45:45Now it's maybe no longer just us, us as
01:45:48engineers doing performing
01:45:50changes on our code, but it's now
01:45:52AI systems performing changes on our
01:45:54code. And this is where the same
01:45:56underlying dynamic is even more
01:45:58severe. If there is a system, if there is
01:46:02some actor here who's
01:46:04changing our code, who is maybe
01:46:07even less competent or less knowledgeable
01:46:10about this, then maybe even
01:46:12more scary to make changes
01:46:14to a system. And if the material here,
01:46:18the house that we're
01:46:18building that you've mentioned,
01:46:20is where it's inviting to have changes be
01:46:24made, that sets an even better foundation
01:46:27for those AI-assisted,
01:46:30for this AI-assisted future. So that's
01:46:33something I love thinking about.
01:46:35Yeah, I agree. I think the guardrails
01:46:41here are so important,
01:46:42right? You want to make sure that,
01:46:44whatever the LLM generates has as little
01:46:49unintended side effects as possible,
01:46:52because it could hallucinate some code.
01:46:55So if you can make sure that
01:46:57the blast radius is as tight,
01:46:59small as possible, then I think you have
01:47:01a really good foundation. Obviously, I
01:47:03don't know where this
01:47:04is heading. Maybe we're going to be
01:47:05completely wrong and that we're not even
01:47:07going to be thinking
01:47:07about code in the same way in the future.
01:47:12But it feels like it's a
01:47:13really good way of ensuring
01:47:16that whatever an LLM generates stays
01:47:20within the intended radius.
01:47:25Exactly. And I think just to round this
01:47:28part out, Effect gives
01:47:30you a middle ground between
01:47:34a natural language like English that
01:47:37might be more intuitive to
01:47:40describe what a system should do,
01:47:41but maybe less concise, as opposed to a
01:47:45type system or code,
01:47:47which can be more concise,
01:47:49but maybe less intuitive. And I feel
01:47:51Effect is the best of
01:47:52both worlds, where you can,
01:47:54through the help of a type system, and
01:47:56here in this case,
01:47:58TypeScript provides a marvelous type
01:48:00system that allows you to give you the
01:48:02correctness benefits that you wouldn't
01:48:04get from English, yet
01:48:06it gives you that more intuitive way to
01:48:09express and compose things. I feel like
01:48:13Effect is converging
01:48:14towards something that's the best of both
01:48:16worlds here, that is
01:48:18actually a wonderful substrate
01:48:20for AIs to also compose
01:48:22systems out of.
01:48:24Wish that the latest versions of LLMs
01:48:26have even better
01:48:27understanding of the latest developments
01:48:28in Effect. But I think you mentioned that
01:48:31you have a nice hack, which is to
01:48:33clone the Effect repository in cursor and
01:48:36then have it look at
01:48:38that while you're coding.
01:48:40Yeah, so that's actually a shout out to
01:48:42our friend Tim
01:48:44Suchanek. He taught me about
01:48:48this little trick, and I've since applied
01:48:50it many times also for other projects.
01:48:52I think we're currently in this uncanny
01:48:54valley, where LLMs always
01:48:57lag behind on the latest and
01:48:59greatest of actual information. The
01:49:02Effect docs, for example, in
01:49:04particular, they have really
01:49:06advanced a lot, got a lot better over the
01:49:09last couple of months. And
01:49:10those LLMs that we're using
01:49:13on a daily basis have not fully caught up
01:49:15to that level yet, and
01:49:17are also sometimes trained
01:49:19on old code snippets, different syntax,
01:49:22etc. And so when you ask
01:49:24them, you might get an outdated
01:49:25response. So what Tim is doing, and since
01:49:29he's taught me about
01:49:31this as well, is basically
01:49:33check out the Effect code base on your
01:49:36computer locally, open
01:49:38Cursor in it, and then
01:49:40Cursor uses the full Effect repo with
01:49:43all the examples, tests,
01:49:44etc. as the context. And then
01:49:46inside of that, you use the Cursor chat
01:49:49to ask your question, and
01:49:51you're going to get a really
01:49:52useful result. So I've been using this a
01:49:55bunch myself, but we're
01:49:57also working on some exciting
01:49:59improvements to the Effect docs, etc.,
01:50:02where we're trying to
01:50:04combine the latest and greatest
01:50:07documentation with some of our own AI
01:50:11developments as well. So stay tuned for
01:50:13that. You won't need
01:50:14those little tricks for too much longer.
01:50:18So Michael,
01:50:19thank you so much for taking
01:50:21out so much of your busy day to share
01:50:24about your experience and journey with
01:50:26Effect. Really greatly
01:50:28appreciate that you share all of that
01:50:31with the entire audience
01:50:32here. Before rounding this out,
01:50:35is there anything else you would like to
01:50:37share with the folks
01:50:38listening? I'm sure that you're
01:50:42very busy building a lot of things, but
01:50:44you're also interested in
01:50:46bringing on more engineers.
01:50:49Anyone in particular who
01:50:51should reach out to you?
01:50:53Yeah, so we are constantly hiring and we
01:50:57are obviously, it's a full TypeScript
01:51:01Effect code base, but we are also very
01:51:04much looking for
01:51:05engineers with an ML background.
01:51:07And we would warmly welcome them even if
01:51:11they don't have
01:51:12specific TypeScript experience.
01:51:14So yeah, if you're interested in working
01:51:18on such a code base, which I
01:51:20think is really, really nice
01:51:22and working on some really interesting
01:51:24LLM related topics,
01:51:27then absolutely reach out.
01:51:30Yeah, I couldn't give you a warmer
01:51:33recommendation to work at
01:51:35Markprompt. Michael, Marie,
01:51:38Elliot, all the folks working at
01:51:40Markprompt are A plus humans. If I
01:51:43wouldn't be doing all of the
01:51:45things I'm doing, I'd strongly consider
01:51:47working with you all as
01:51:49well. So whoever gets a chance
01:51:50to work with you, I think you're making a
01:51:53very smart decision. So
01:51:55now moving back my focus to
01:51:57you, Michael, thank you so much again for
01:52:00taking time, sharing all of your
01:52:03experience and all of
01:52:05those anecdotes with us. I greatly
01:52:06appreciate it. Well, thank
01:52:08you, Johannes. Always a pleasure
01:52:09to speak with you. Awesome.
01:52:12Thank you so much. Thank you.