1
01:00:00,000 --> 01:00:01,000
As an engineer, you want to build

2
01:00:01,000 --> 01:00:01,958
features, you want to

3
01:00:01,958 --> 01:00:03,791
build like real robust systems.

4
01:00:04,125 --> 01:00:05,083
You want to spend ideally

5
01:00:05,083 --> 01:00:06,708
all your time doing that.

6
01:00:06,958 --> 01:00:08,291
You don't want to spend your time

7
01:00:08,291 --> 01:00:09,291
fighting the language,

8
01:00:09,708 --> 01:00:10,958
building something that, you

9
01:00:10,958 --> 01:00:12,666
know, the language was not meant for.

10
01:00:12,666 --> 01:00:13,458
To give you an example,

11
01:00:13,458 --> 01:00:14,500
like concurrency in TypeScript.

12
01:00:14,833 --> 01:00:17,291
You want a way to build a concurrent

13
01:00:17,291 --> 01:00:18,375
system where you're

14
01:00:18,375 --> 01:00:19,375
thinking about what is

15
01:00:19,375 --> 01:00:20,750
the system actually doing rather than

16
01:00:20,750 --> 01:00:22,125
like setting up all the

17
01:00:22,125 --> 01:00:23,375
boilerplate in order to

18
01:00:23,541 --> 01:00:24,916
have that system in place.

19
01:00:25,458 --> 01:00:27,333
So I would say Effect really

20
01:00:27,333 --> 01:00:28,833
gives you the right premise.

21
01:00:28,875 --> 01:00:30,416
So now that we've completed this

22
01:00:30,416 --> 01:00:31,666
migration, kind of feel

23
01:00:31,666 --> 01:00:33,208
like this is the end game feels

24
01:00:33,208 --> 01:00:35,541
like more stable and at least if we

25
01:00:35,541 --> 01:00:36,666
continue building our

26
01:00:36,666 --> 01:00:38,000
code base on TypeScript with

27
01:00:38,041 --> 01:00:39,750
Effect, it doesn't feel like we're going

28
01:00:39,750 --> 01:00:41,416
to spend many more like

29
01:00:41,416 --> 01:00:43,041
cycles, like refactoring

30
01:00:43,041 --> 01:00:43,750
the code.

31
01:00:47,291 --> 01:00:49,375
Welcome to Cause & Effect, a podcast

32
01:00:49,375 --> 01:00:50,291
about the TypeScript

33
01:00:50,291 --> 01:00:51,958
library and ecosystem called

34
01:00:51,958 --> 01:00:54,083
Effect, helping engineers to build

35
01:00:54,083 --> 01:00:55,208
production-ready software.

36
01:00:56,041 --> 01:00:58,000
I'm your host, Johannes Schickling, and I've

37
01:00:58,000 --> 01:00:58,750
been building with

38
01:00:58,750 --> 01:01:00,000
Effect for over four years.

39
01:01:00,583 --> 01:01:02,541
With this podcast, I want to help others

40
01:01:02,541 --> 01:01:04,333
understand the powers and

41
01:01:04,333 --> 01:01:05,708
benefits of using Effect.

42
01:01:06,625 --> 01:01:08,583
In this episode, I'm talking to Michael

43
01:01:08,583 --> 01:01:10,375
Fester, co-founder of

44
01:01:10,375 --> 01:01:12,333
Markprompt, an AI-based customer

45
01:01:12,333 --> 01:01:13,208
support platform.

46
01:01:13,916 --> 01:01:16,083
In this conversation, we explore how

47
01:01:16,083 --> 01:01:17,333
Markprompt uses Effect

48
01:01:17,333 --> 01:01:19,291
across its entire architecture,

49
01:01:20,041 --> 01:01:21,958
including API and RPC endpoints,

50
01:01:22,500 --> 01:01:24,125
long-running workflows, and their

51
01:01:24,125 --> 01:01:25,166
customer-facing product.

52
01:01:25,666 --> 01:01:26,541
Let's get into it.

53
01:01:28,000 --> 01:01:28,958
Hey, welcome Michael.

54
01:01:29,250 --> 01:01:30,416
So nice to have you on the

55
01:01:30,416 --> 01:01:31,583
Cause & Effect Podcast.

56
01:01:31,583 --> 01:01:32,041
How are you doing?

57
01:01:32,708 --> 01:01:33,250
I'm good.

58
01:01:33,250 --> 01:01:33,666
Thank you.

59
01:01:33,666 --> 01:01:35,416
I'm really happy to be here.

60
01:01:35,416 --> 01:01:36,916
It's been, I guess it's been a while that

61
01:01:36,916 --> 01:01:37,666
we're trying to

62
01:01:37,666 --> 01:01:39,541
organize this, but I'm very

63
01:01:39,541 --> 01:01:40,708
happy that we're doing it now.

64
01:01:41,458 --> 01:01:41,666
Yeah.

65
01:01:41,833 --> 01:01:44,250
I mean, you're super, super busy.

66
01:01:44,458 --> 01:01:45,458
You're based in San

67
01:01:45,458 --> 01:01:47,791
Francisco building an AI company.

68
01:01:48,000 --> 01:01:50,083
So I'm really, really happy that you took

69
01:01:50,083 --> 01:01:51,625
the time to share

70
01:01:51,625 --> 01:01:53,041
your story about Effect.

71
01:01:53,875 --> 01:01:56,000
Maybe you can share a little bit about

72
01:01:56,000 --> 01:01:56,958
yourself, your

73
01:01:56,958 --> 01:01:58,625
background and what are you doing?

74
01:01:59,958 --> 01:02:00,625
Yeah, sure.

75
01:02:00,958 --> 01:02:02,208
So I have a background.

76
01:02:02,208 --> 01:02:03,208
I started in academia.

77
01:02:03,500 --> 01:02:04,625
Actually, I was doing

78
01:02:04,625 --> 01:02:05,500
research in mathematics.

79
01:02:05,708 --> 01:02:07,208
Then I started getting into AI and I

80
01:02:07,208 --> 01:02:08,083
built my first AI

81
01:02:08,083 --> 01:02:10,125
company in Europe, specialized

82
01:02:10,250 --> 01:02:11,750
on device voice recognition.

83
01:02:12,291 --> 01:02:13,916
And we got acquired by Sonos.

84
01:02:14,291 --> 01:02:17,333
And since then I moved here to San

85
01:02:17,333 --> 01:02:19,458
Francisco for my next

86
01:02:19,458 --> 01:02:21,750
venture, which is we're building

87
01:02:22,666 --> 01:02:24,666
AI infrastructure for customer support.

88
01:02:25,375 --> 01:02:26,916
So this is all like posts,

89
01:02:27,375 --> 01:02:29,375
chat GPT, GPT 4 coming out.

90
01:02:30,083 --> 01:02:31,583
And we saw this, this incredible

91
01:02:31,583 --> 01:02:32,958
opportunity to start

92
01:02:32,958 --> 01:02:35,541
working in this space.

93
01:02:35,625 --> 01:02:36,875
That is awesome.

94
01:02:36,875 --> 01:02:40,166
And I highly encourage everyone who is

95
01:02:40,166 --> 01:02:41,791
like interested in AI,

96
01:02:41,791 --> 01:02:43,333
particularly is looking

97
01:02:43,333 --> 01:02:46,500
for a better customer support solution to

98
01:02:46,500 --> 01:02:47,583
check out Markprompt.

99
01:02:48,041 --> 01:02:50,166
Can you share about a few companies who

100
01:02:50,166 --> 01:02:51,458
are already using Markprompt?

101
01:02:51,833 --> 01:02:52,291
Yeah, sure.

102
01:02:52,541 --> 01:02:55,250
So we've been working very closely with

103
01:02:55,250 --> 01:02:56,458
some companies very

104
01:02:56,458 --> 01:02:57,416
early on in the process.

105
01:02:57,708 --> 01:02:58,500
Actually, that's really interesting.

106
01:02:58,833 --> 01:03:00,958
Vercel started using us as one of our

107
01:03:00,958 --> 01:03:01,750
first customers,

108
01:03:01,750 --> 01:03:03,375
actually ElevenLabs, Replicate.

109
01:03:03,833 --> 01:03:05,666
Things are just moving so fast.

110
01:03:05,666 --> 01:03:08,541
So our approach here is not so much of a,

111
01:03:08,541 --> 01:03:09,375
you know, we have a

112
01:03:09,375 --> 01:03:10,583
vision of how things will

113
01:03:10,583 --> 01:03:11,583
end up, right?

114
01:03:11,583 --> 01:03:13,750
It's very much like a learning process,

115
01:03:13,750 --> 01:03:14,541
working very, very

116
01:03:14,541 --> 01:03:16,541
closely with customers, hand in

117
01:03:16,541 --> 01:03:17,916
hand getting their feedback,

118
01:03:17,916 --> 01:03:19,791
understanding together, how

119
01:03:19,791 --> 01:03:21,625
this thing is evolving, how

120
01:03:21,625 --> 01:03:23,625
we can improve, you know, the behavior of

121
01:03:23,625 --> 01:03:24,708
the LLMs or how we can

122
01:03:24,708 --> 01:03:25,958
extend the use cases.

123
01:03:26,625 --> 01:03:28,666
So this has been a very different way, I

124
01:03:28,666 --> 01:03:29,333
would say, of building

125
01:03:29,333 --> 01:03:30,708
a company from the past,

126
01:03:30,708 --> 01:03:32,333
because it's so new to

127
01:03:32,333 --> 01:03:33,250
everyone in the space.

128
01:03:33,916 --> 01:03:35,083
And we're just like scratching the

129
01:03:35,083 --> 01:03:35,875
surface of the

130
01:03:35,875 --> 01:03:38,333
opportunities of building these systems

131
01:03:38,333 --> 01:03:39,958
for you know, down the line.

132
01:03:40,833 --> 01:03:41,291
That's awesome.

133
01:03:41,541 --> 01:03:44,000
So before we go into the technical parts,

134
01:03:44,500 --> 01:03:45,416
maybe you can share

135
01:03:45,416 --> 01:03:47,208
through the lens of one

136
01:03:47,208 --> 01:03:49,125
of your typical customers, what

137
01:03:49,125 --> 01:03:51,000
Markpompt does and which

138
01:03:51,000 --> 01:03:53,083
problems it solves for some

139
01:03:53,083 --> 01:03:53,833
of those customers.

140
01:03:54,875 --> 01:03:55,000
Sure.

141
01:03:55,041 --> 01:03:57,333
So there's multiple facets of this

142
01:03:57,333 --> 01:03:58,916
running a support

143
01:03:58,916 --> 01:04:01,333
operation is it's not a one size

144
01:04:01,333 --> 01:04:02,125
fits all.

145
01:04:02,125 --> 01:04:04,250
Every company has their own ways of, you

146
01:04:04,250 --> 01:04:05,958
know, the nature of

147
01:04:05,958 --> 01:04:07,625
customer issues, the way that

148
01:04:07,625 --> 01:04:08,791
they engage with customers,

149
01:04:09,041 --> 01:04:10,958
is it like direct contact?

150
01:04:11,208 --> 01:04:14,583
Is it, you know, is it mostly self serve?

151
01:04:14,791 --> 01:04:16,375
Technical challenges are very different

152
01:04:16,375 --> 01:04:18,500
from one company to the other.

153
01:04:18,916 --> 01:04:20,625
So we offer really an

154
01:04:20,625 --> 01:04:21,500
end to end solution.

155
01:04:21,875 --> 01:04:23,208
So there's multiple

156
01:04:23,208 --> 01:04:24,791
components in our system.

157
01:04:24,791 --> 01:04:26,500
It all starts with understanding your

158
01:04:26,500 --> 01:04:28,458
system of record, which is

159
01:04:28,458 --> 01:04:30,250
things like your underlying

160
01:04:30,416 --> 01:04:33,291
customer knowledge, your, you know, your

161
01:04:33,291 --> 01:04:37,708
documentation, your CRM, the API is that

162
01:04:37,708 --> 01:04:39,250
you use for automating

163
01:04:39,250 --> 01:04:41,333
parts of your support.

164
01:04:41,750 --> 01:04:43,166
And we connect all that together.

165
01:04:43,166 --> 01:04:45,833
And then we build applications that are

166
01:04:45,833 --> 01:04:46,958
either customer facing

167
01:04:46,958 --> 01:04:49,458
or agent facing so and use

168
01:04:49,458 --> 01:04:50,958
internally for the company.

169
01:04:51,041 --> 01:04:52,666
So it can be, you know, everything from,

170
01:04:52,666 --> 01:04:55,458
you know, your contact form powered by AI

171
01:04:55,666 --> 01:04:58,041
to your chatbot to your

172
01:04:58,041 --> 01:05:00,625
Slack and Discord bots, right?

173
01:05:00,833 --> 01:05:01,333
This is customer

174
01:05:01,333 --> 01:05:04,041
facing email order replies.

175
01:05:04,375 --> 01:05:08,083
So you send an email and the AI agent

176
01:05:08,083 --> 01:05:09,458
will start, you know,

177
01:05:09,833 --> 01:05:11,500
trying to resolve the issue

178
01:05:11,500 --> 01:05:12,000
for you.

179
01:05:12,333 --> 01:05:13,250
And it might be possible

180
01:05:13,250 --> 01:05:15,291
that it resolves it fully.

181
01:05:16,250 --> 01:05:17,541
And if not, it's going to ask you for all

182
01:05:17,541 --> 01:05:19,791
the questions that the team then needs to

183
01:05:19,791 --> 01:05:21,791
use once you know, the ticket

184
01:05:21,791 --> 01:05:23,125
hits the inbox internally.

185
01:05:23,333 --> 01:05:25,125
And then there's the all the features

186
01:05:25,125 --> 01:05:26,708
which are internal

187
01:05:26,708 --> 01:05:28,583
facing for the support

188
01:05:28,583 --> 01:05:30,916
team to be able to streamline their work.

189
01:05:31,250 --> 01:05:32,583
Because the truth is that customer

190
01:05:32,583 --> 01:05:36,625
support before AI involved

191
01:05:36,625 --> 01:05:38,916
a lot of essentially like

192
01:05:38,958 --> 01:05:41,000
robotic work, just answering the same

193
01:05:41,000 --> 01:05:42,291
questions over and over again.

194
01:05:42,625 --> 01:05:44,250
This is not super engaging

195
01:05:44,250 --> 01:05:45,500
and exciting just to have

196
01:05:45,500 --> 01:05:46,416
to answer the same

197
01:05:46,416 --> 01:05:47,375
question over and over again.

198
01:05:47,625 --> 01:05:49,458
So if you can start like taking that

199
01:05:49,458 --> 01:05:50,333
burden off of your

200
01:05:50,333 --> 01:05:52,625
shoulders and help you, you know,

201
01:05:52,875 --> 01:05:56,291
work on more like high leverage strategic

202
01:05:56,291 --> 01:05:58,625
questions, then, you

203
01:05:58,625 --> 01:05:59,375
know, we can really help

204
01:05:59,375 --> 01:06:00,500
streamline the support operation.

205
01:06:00,708 --> 01:06:01,916
what happens when you've put

206
01:06:01,916 --> 01:06:03,625
an AI or both like customer

207
01:06:03,625 --> 01:06:06,375
facing and agent facing, then you can

208
01:06:06,375 --> 01:06:07,041
start, you know,

209
01:06:07,750 --> 01:06:09,208
extracting a lot of intelligence,

210
01:06:09,208 --> 01:06:10,666
a lot of knowledge, because you're really

211
01:06:10,666 --> 01:06:11,583
at the nerve center

212
01:06:11,583 --> 01:06:13,375
in a company, you are,

213
01:06:13,625 --> 01:06:15,333
you know, the interface between your

214
01:06:15,333 --> 01:06:17,708
customers and your company, right?

215
01:06:18,000 --> 01:06:20,583
So you have so much like knowledge that

216
01:06:20,583 --> 01:06:21,916
often just gets siloed

217
01:06:21,916 --> 01:06:23,166
within the support team,

218
01:06:23,166 --> 01:06:23,375
right?

219
01:06:23,375 --> 01:06:25,791
It's it's actually very rare that support

220
01:06:25,791 --> 01:06:28,458
team reports to product, right?

221
01:06:28,958 --> 01:06:29,500
And I think that's a

222
01:06:29,500 --> 01:06:30,375
that's really a problem.

223
01:06:30,583 --> 01:06:32,375
But if we can start rooting

224
01:06:32,375 --> 01:06:33,875
out all this insight and

225
01:06:33,875 --> 01:06:35,166
knowledge, we can start

226
01:06:35,166 --> 01:06:36,333
having a really, really good

227
01:06:36,333 --> 01:06:37,916
understanding on, you know,

228
01:06:37,916 --> 01:06:39,416
product shortcomings, where

229
01:06:39,416 --> 01:06:40,625
the engineering team might,

230
01:06:40,625 --> 01:06:42,708
you know, put some effort, right?

231
01:06:43,083 --> 01:06:44,625
Because this is where your customers have

232
01:06:44,625 --> 01:06:46,250
been experiencing a

233
01:06:46,250 --> 01:06:47,333
lot of friction, right?

234
01:06:47,666 --> 01:06:49,208
So we can start generating these

235
01:06:49,208 --> 01:06:51,375
reporting and all sorts of

236
01:06:51,375 --> 01:06:52,833
other insights that can help

237
01:06:53,208 --> 01:06:54,750
you as a company

238
01:06:54,750 --> 01:06:55,708
streamline your operations,

239
01:06:56,291 --> 01:06:57,583
things like spotting knowledge

240
01:06:57,583 --> 01:06:59,541
gaps, right, helping you write, you know,

241
01:06:59,541 --> 01:07:00,750
keeping your your

242
01:07:00,750 --> 01:07:02,000
documentation up to date,

243
01:07:02,000 --> 01:07:02,958
these are all things that

244
01:07:02,958 --> 01:07:04,625
we can start also working on.

245
01:07:05,041 --> 01:07:05,791
So this concept of

246
01:07:05,791 --> 01:07:07,875
agent is very versatile.

247
01:07:08,208 --> 01:07:10,041
The agents can solve issues, they can,

248
01:07:10,041 --> 01:07:11,500
you know, answer emails,

249
01:07:11,500 --> 01:07:12,541
but they can also start

250
01:07:12,541 --> 01:07:14,041
being tasked of gathering

251
01:07:14,041 --> 01:07:15,375
insights and producing new

252
01:07:15,375 --> 01:07:16,333
knowledge and keeping your

253
01:07:16,333 --> 01:07:17,625
system of record,

254
01:07:17,625 --> 01:07:18,458
always up to date.

255
01:07:18,458 --> 01:07:19,708
So there's really a lot of

256
01:07:19,708 --> 01:07:20,875
things that need to happen.

257
01:07:20,875 --> 01:07:22,041
You cannot approach the

258
01:07:22,041 --> 01:07:23,041
problem just from one

259
01:07:23,041 --> 01:07:24,750
angle, you really want to tie

260
01:07:24,750 --> 01:07:26,291
the whole thing together, because this is

261
01:07:26,291 --> 01:07:27,083
where you start creating

262
01:07:27,083 --> 01:07:28,250
these positive feedback

263
01:07:28,291 --> 01:07:30,958
loops, so called data flywheels, right,

264
01:07:31,041 --> 01:07:32,208
that enable you to

265
01:07:32,208 --> 01:07:33,416
start deploying the solution

266
01:07:33,416 --> 01:07:34,625
and trust it that it's

267
01:07:34,625 --> 01:07:35,750
operating really well.

268
01:07:36,458 --> 01:07:37,083
So yeah, there's,

269
01:07:37,083 --> 01:07:38,625
there's a lot of things to it.

270
01:07:38,666 --> 01:07:41,458
That sounds fascinating, and also quite

271
01:07:41,458 --> 01:07:42,958
complex in terms of the

272
01:07:42,958 --> 01:07:44,708
different surface areas, etc.

273
01:07:45,208 --> 01:07:46,083
So maybe we can go

274
01:07:46,083 --> 01:07:47,541
slightly more technical.

275
01:07:47,791 --> 01:07:49,791
And before we go into all of the Effect's

276
01:07:49,791 --> 01:07:52,416
specifics, can you more from like an

277
01:07:52,416 --> 01:07:53,458
engineering perspective

278
01:07:53,750 --> 01:07:56,000
provide an overview over your system?

279
01:07:56,875 --> 01:07:59,000
And which different high level components

280
01:07:59,000 --> 01:08:00,958
it's composed out of?

281
01:08:01,708 --> 01:08:01,916
Sure.

282
01:08:02,125 --> 01:08:04,875
So this is a, you know, apart from the

283
01:08:04,875 --> 01:08:06,666
machine learning things,

284
01:08:06,666 --> 01:08:08,041
the LLM things, this is a

285
01:08:08,041 --> 01:08:09,625
classical, you know, setup.

286
01:08:09,625 --> 01:08:11,041
there's some servers, both

287
01:08:11,083 --> 01:08:13,500
like short, like serverless instances for

288
01:08:13,500 --> 01:08:14,875
API endpoints, then

289
01:08:14,875 --> 01:08:15,750
there's some long running

290
01:08:16,166 --> 01:08:18,875
servers to do things like, you know, pre

291
01:08:18,875 --> 01:08:21,333
processing data, post

292
01:08:21,333 --> 01:08:23,791
processing, interactions.

293
01:08:23,916 --> 01:08:25,041
So yeah, there's a there's a bunch of

294
01:08:25,041 --> 01:08:25,875
servers here, everything

295
01:08:25,875 --> 01:08:27,041
is in node, everything is

296
01:08:27,291 --> 01:08:28,375
or TypeScript.

297
01:08:29,041 --> 01:08:32,125
The front end is a React application.

298
01:08:32,583 --> 01:08:35,958
So both we have a dashboard, which is a V

299
01:08:35,958 --> 01:08:37,583
duplication, there is

300
01:08:37,583 --> 01:08:38,708
some integrations

301
01:08:38,708 --> 01:08:39,916
inside of Salesforce,

302
01:08:39,916 --> 01:08:41,750
Zendesk, Slack, and so on.

303
01:08:41,750 --> 01:08:43,875
So it's a classical full

304
01:08:43,875 --> 01:08:46,625
stack, React TypeScript application.

305
01:08:47,541 --> 01:08:49,750
So you've built quite an expansive system

306
01:08:49,750 --> 01:08:51,375
here and building all

307
01:08:51,375 --> 01:08:52,250
of that in TypeScript

308
01:08:52,291 --> 01:08:54,291
I think TypeScript is sort of notorious

309
01:08:54,291 --> 01:08:55,958
for only scratching the

310
01:08:55,958 --> 01:08:57,250
surface and only covering

311
01:08:57,250 --> 01:08:58,083
the happy path.

312
01:08:58,750 --> 01:09:00,541
There's a lot of things that can go wrong

313
01:09:00,541 --> 01:09:03,208
in all of those systems, integrating with

314
01:09:03,208 --> 01:09:04,125
different systems.

315
01:09:04,750 --> 01:09:06,916
All of those things I think have led you

316
01:09:06,916 --> 01:09:08,666
to take a more serious

317
01:09:08,666 --> 01:09:10,166
look at Effect and ultimately

318
01:09:10,208 --> 01:09:10,958
adopting it.

319
01:09:11,375 --> 01:09:14,708
So can you share that journey of going

320
01:09:14,708 --> 01:09:16,041
from a non-Effect code

321
01:09:16,041 --> 01:09:18,583
base to converting step

322
01:09:18,583 --> 01:09:19,458
by step to Effect?

323
01:09:20,166 --> 01:09:22,875
Sure, so obviously there's the common

324
01:09:22,875 --> 01:09:24,791
complexity increase that

325
01:09:24,791 --> 01:09:25,833
happens when you're building

326
01:09:25,833 --> 01:09:27,791
a product and putting it into production.

327
01:09:27,791 --> 01:09:29,833
So as you add features and so on, then

328
01:09:29,833 --> 01:09:31,875
you hit sort of a ceiling

329
01:09:31,875 --> 01:09:33,333
and then you start assessing

330
01:09:33,333 --> 01:09:35,333
the situation and then you might start

331
01:09:35,333 --> 01:09:36,708
refactoring and so on.

332
01:09:36,708 --> 01:09:39,958
And then next phase, you hit some other

333
01:09:39,958 --> 01:09:41,250
limitations and then you

334
01:09:41,250 --> 01:09:43,291
reassess again the situation.

335
01:09:44,041 --> 01:09:45,916
So that's just the common thing of

336
01:09:45,916 --> 01:09:46,833
working on an

337
01:09:46,833 --> 01:09:48,458
increasingly growing code base.

338
01:09:49,500 --> 01:09:51,791
But then there's LLMs and these are

339
01:09:51,791 --> 01:09:54,958
non-deterministic systems and it poses

340
01:09:54,958 --> 01:09:56,166
some completely new kinds

341
01:09:56,166 --> 01:09:56,833
of challenges.

342
01:09:56,833 --> 01:09:58,916
How do you monitor the behavior of the

343
01:09:58,916 --> 01:09:59,666
system, for instance?

344
01:10:00,500 --> 01:10:02,708
How do you deal with readable streams

345
01:10:02,708 --> 01:10:04,958
instead of just sending over a payload?

346
01:10:05,416 --> 01:10:07,333
This has the potential to making your

347
01:10:07,333 --> 01:10:08,375
code base more complex

348
01:10:08,375 --> 01:10:10,666
if you need to stream some

349
01:10:10,666 --> 01:10:12,375
tokens down to the customer, but you

350
01:10:12,375 --> 01:10:13,375
actually also need to

351
01:10:13,375 --> 01:10:16,125
store these chunks on your own

352
01:10:16,125 --> 01:10:16,916
for post-processing.

353
01:10:17,291 --> 01:10:18,125
How do you deal with that?

354
01:10:18,625 --> 01:10:19,416
TypeScript doesn't give you

355
01:10:19,416 --> 01:10:22,041
some great answers to this.

356
01:10:22,458 --> 01:10:24,166
How do you deal with reliability?

357
01:10:24,750 --> 01:10:27,875
OpenAI and Anthropic and so on, they offer

358
01:10:27,875 --> 01:10:30,291
a service which is in high demand.

359
01:10:31,000 --> 01:10:33,125
We are in a period right

360
01:10:33,125 --> 01:10:34,416
now with scarce resources.

361
01:10:35,250 --> 01:10:37,458
So these APIs, they go down and they

362
01:10:37,458 --> 01:10:38,875
actually go down more

363
01:10:38,875 --> 01:10:39,875
than you would think.

364
01:10:40,250 --> 01:10:42,458
And so how do you build fallback

365
01:10:42,458 --> 01:10:44,833
mechanisms so that, say that

366
01:10:44,833 --> 01:10:46,125
OpenAI is down as your main

367
01:10:46,125 --> 01:10:48,833
provider, your customers cannot be down.

368
01:10:48,833 --> 01:10:49,750
If OpenAI is down,

369
01:10:49,750 --> 01:10:50,541
that's not their problem.

370
01:10:50,791 --> 01:10:51,416
That's our problem.

371
01:10:52,125 --> 01:10:53,541
So how do you build a

372
01:10:53,541 --> 01:10:55,458
fallback system to Anthropic?

373
01:10:55,458 --> 01:10:58,625
What happens a few weeks ago when OpenAI

374
01:10:58,625 --> 01:10:59,916
was down for, I think,

375
01:11:00,041 --> 01:11:01,208
five hours and then the

376
01:11:01,208 --> 01:11:04,250
entire industry shifts towards Anthropic

377
01:11:04,250 --> 01:11:05,166
that just has this

378
01:11:05,166 --> 01:11:06,958
spike that they're unable

379
01:11:07,000 --> 01:11:08,708
to deal with?

380
01:11:08,708 --> 01:11:11,583
So they are experiencing outage or just

381
01:11:11,583 --> 01:11:13,125
very degraded performance.

382
01:11:13,750 --> 01:11:15,541
There's outage and then there's actually

383
01:11:15,541 --> 01:11:16,500
performance, the

384
01:11:16,500 --> 01:11:19,083
speed of tokens and so on.

385
01:11:19,958 --> 01:11:22,916
All that, there's no good answer, no

386
01:11:22,916 --> 01:11:25,750
clear best practice in

387
01:11:25,750 --> 01:11:27,125
vanilla TypeScript to deal

388
01:11:27,125 --> 01:11:27,666
with these things.

389
01:11:28,208 --> 01:11:29,916
And then there's the fact that we are a

390
01:11:29,916 --> 01:11:31,541
startup working in a

391
01:11:31,541 --> 01:11:33,250
fast-paced environment where

392
01:11:33,250 --> 01:11:35,625
things change all the time.

393
01:11:36,166 --> 01:11:37,750
And we want to be efficient and we want

394
01:11:37,750 --> 01:11:39,291
to be able to not deal

395
01:11:39,291 --> 01:11:40,916
with all the complexity

396
01:11:41,125 --> 01:11:42,916
and all the problems and down times and

397
01:11:42,916 --> 01:11:44,833
reliability, but we need to

398
01:11:44,833 --> 01:11:46,458
be effective in shipping new

399
01:11:46,458 --> 01:11:47,708
features to constantly

400
01:11:47,708 --> 01:11:49,291
meet up with the demand.

401
01:11:49,875 --> 01:11:50,625
the zero to one of

402
01:11:50,625 --> 01:11:51,875
building a company here.

403
01:11:51,875 --> 01:11:54,125
So there's multiple factors that really

404
01:11:54,125 --> 01:11:55,833
made us think hard about

405
01:11:55,833 --> 01:11:57,916
what would be the foundation

406
01:11:58,083 --> 01:12:00,625
for us to be able to operate really fast

407
01:12:00,625 --> 01:12:02,125
with a small set of

408
01:12:02,125 --> 01:12:04,416
resources from a startup and

409
01:12:04,500 --> 01:12:07,458
be a highly reliable solution because we

410
01:12:07,458 --> 01:12:08,958
are catering to larger

411
01:12:08,958 --> 01:12:10,083
companies, enterprise

412
01:12:10,083 --> 01:12:10,541
companies.

413
01:12:10,875 --> 01:12:13,333
So reliability is just really key.

414
01:12:13,791 --> 01:12:15,500
Obviously, I can talk a lot about the

415
01:12:15,500 --> 01:12:18,750
whole telemetry part of

416
01:12:18,750 --> 01:12:20,041
things, making sure everything

417
01:12:20,041 --> 01:12:21,708
is properly monitored and that we can

418
01:12:21,708 --> 01:12:24,041
actually spot when things

419
01:12:24,041 --> 01:12:25,750
go wrong before our customers

420
01:12:25,750 --> 01:12:28,125
even see it and then we can take action.

421
01:12:28,125 --> 01:12:29,333
So there's a bunch of things here.

422
01:12:29,833 --> 01:12:31,708
And Effect just came at a very good

423
01:12:31,708 --> 01:12:33,916
moment where we still had

424
01:12:33,916 --> 01:12:36,166
a sufficiently small code

425
01:12:36,166 --> 01:12:38,291
base that we could actually start

426
01:12:38,291 --> 01:12:39,750
seriously thinking about

427
01:12:39,750 --> 01:12:40,958
completely converting it to

428
01:12:40,958 --> 01:12:41,125
Effect.

429
01:12:41,666 --> 01:12:42,916
So the timing was really good.

430
01:12:43,750 --> 01:12:45,291
So you've mentioned in regards to

431
01:12:45,291 --> 01:12:46,750
adopting Effect for the

432
01:12:46,750 --> 01:12:48,375
sake of improving reliability,

433
01:12:49,083 --> 01:12:52,250
one specific use case was that Markbrom

434
01:12:52,250 --> 01:12:54,625
is using LLMs such as

435
01:12:54,625 --> 01:12:56,125
the products provided by

436
01:12:56,125 --> 01:12:56,541
OpenAI.

437
01:12:56,958 --> 01:12:58,958
And if they go down, you need to fall

438
01:12:58,958 --> 01:13:00,041
back to another system.

439
01:13:00,250 --> 01:13:02,208
And in case that system also goes down,

440
01:13:02,541 --> 01:13:03,791
fall back to yet another one.

441
01:13:04,333 --> 01:13:07,000
All of that is helping to improve the

442
01:13:07,000 --> 01:13:08,916
reliability of Markprompt.

443
01:13:10,291 --> 01:13:12,125
Which other challenges did you face

444
01:13:12,125 --> 01:13:14,041
similar to that one in

445
01:13:14,041 --> 01:13:15,458
regards to reliability and

446
01:13:15,458 --> 01:13:16,791
how did you improve

447
01:13:16,791 --> 01:13:18,125
reliability through Effect?

448
01:13:19,166 --> 01:13:21,875
I mean, there's lots of examples where

449
01:13:21,875 --> 01:13:23,750
Effect has helped us

450
01:13:23,750 --> 01:13:24,875
consolidate our system.

451
01:13:25,125 --> 01:13:28,333
One example is one day we woke up and we

452
01:13:28,333 --> 01:13:29,250
realized that we were under

453
01:13:29,250 --> 01:13:32,208
attack by a malicious hacker

454
01:13:32,375 --> 01:13:35,750
who was interacting with a public facing

455
01:13:35,750 --> 01:13:37,916
deployment of Markprompt and

456
01:13:37,916 --> 01:13:40,208
sending, I think, 20 million

457
01:13:40,208 --> 01:13:43,166
requests per hour.

458
01:13:43,500 --> 01:13:46,166
And this was across the globe, so it was

459
01:13:46,166 --> 01:13:47,708
kind of hard to deal with.

460
01:13:47,708 --> 01:13:50,458
So Ethan Niser, he spent the summer with

461
01:13:50,458 --> 01:13:53,583
us and he's been working

462
01:13:53,583 --> 01:13:54,750
on a lot of Effect-related

463
01:13:54,833 --> 01:13:56,666
things and on his first day,

464
01:13:56,833 --> 01:13:58,708
this attack started happening.

465
01:13:58,708 --> 01:14:02,000
And so he built this great rate limiting

466
01:14:02,000 --> 01:14:03,291
system in the middleware

467
01:14:03,291 --> 01:14:04,708
that is capable of looking

468
01:14:04,708 --> 01:14:08,250
at multiple facets of a payload.

469
01:14:08,250 --> 01:14:09,541
And the interesting thing here is that

470
01:14:09,541 --> 01:14:11,000
you cannot just rely

471
01:14:11,000 --> 01:14:12,791
on IP and fingerprinting

472
01:14:12,791 --> 01:14:13,250
and so on.

473
01:14:13,250 --> 01:14:14,833
You actually also want to start looking

474
01:14:14,833 --> 01:14:16,375
at the LLM payload itself.

475
01:14:16,375 --> 01:14:18,125
What kinds of messages is there, pattern

476
01:14:18,125 --> 01:14:20,000
that we can spot here in

477
01:14:20,000 --> 01:14:22,250
the nature of the requests?

478
01:14:22,250 --> 01:14:24,208
And so it's a multi-tiered rate limiting

479
01:14:24,208 --> 01:14:25,750
system that is very easy

480
01:14:25,750 --> 01:14:27,208
to automatically trigger

481
01:14:27,208 --> 01:14:28,375
and also manually trigger.

482
01:14:28,375 --> 01:14:30,541
So this is an example also where building

483
01:14:30,541 --> 01:14:33,916
with composability has just allowed us to

484
01:14:34,250 --> 01:14:35,375
build a fairly sophisticated

485
01:14:35,375 --> 01:14:37,458
system here, which just works.

486
01:14:38,291 --> 01:14:39,583
We are now very

487
01:14:39,583 --> 01:14:40,750
confident that it just works.

488
01:14:40,750 --> 01:14:42,083
And by the way, one of the reasons that

489
01:14:42,083 --> 01:14:43,083
we're confident that it

490
01:14:43,083 --> 01:14:44,333
works is that it's very

491
01:14:44,333 --> 01:14:46,250
easy to test because the whole dependency

492
01:14:46,250 --> 01:14:47,791
injection story is

493
01:14:47,791 --> 01:14:48,958
just such a natural thing

494
01:14:48,958 --> 01:14:49,666
to do.

495
01:14:49,666 --> 01:14:51,291
You just operate a provider and you can

496
01:14:51,291 --> 01:14:53,458
very easily simulate a

497
01:14:53,458 --> 01:14:55,291
situation that is hard to

498
01:14:55,291 --> 01:14:56,541
reproduce with other means.

499
01:14:56,583 --> 01:14:59,250
So dependency injection, I would say, is

500
01:14:59,250 --> 01:15:00,458
a huge factor to the

501
01:15:00,458 --> 01:15:01,791
reliability because we

502
01:15:01,791 --> 01:15:05,458
can restart testing all sorts of

503
01:15:05,458 --> 01:15:06,583
different combinations of

504
01:15:06,583 --> 01:15:08,583
non-happy paths and building

505
01:15:08,583 --> 01:15:12,083
that with just change or service that you

506
01:15:12,083 --> 01:15:13,208
provide is just very,

507
01:15:13,208 --> 01:15:14,875
very easy with Effect.

508
01:15:14,875 --> 01:15:15,958
Telemetry is obviously a thing.

509
01:15:16,000 --> 01:15:19,750
So I think that the whole testing story

510
01:15:19,750 --> 01:15:22,000
is not just about one thing.

511
01:15:22,000 --> 01:15:23,208
You want to do unit tests.

512
01:15:23,208 --> 01:15:25,333
You want to do integration tests with

513
01:15:25,333 --> 01:15:26,500
dependency injection.

514
01:15:26,500 --> 01:15:28,166
You also really want to have a full

515
01:15:28,166 --> 01:15:29,083
understanding of what's going

516
01:15:29,083 --> 01:15:30,250
on when you are in production.

517
01:15:31,375 --> 01:15:33,083
And so being able to have good traces,

518
01:15:33,750 --> 01:15:35,000
good logging of every

519
01:15:35,000 --> 01:15:36,208
component of your system

520
01:15:36,666 --> 01:15:37,500
is non-trivial.

521
01:15:38,625 --> 01:15:41,708
And so we rely heavily on telemetry and

522
01:15:41,708 --> 01:15:43,875
Effect allows us to just

523
01:15:43,875 --> 01:15:45,750
add spans everywhere in

524
01:15:45,750 --> 01:15:46,916
a very, very simple way.

525
01:15:46,916 --> 01:15:48,333
And it just naturally fits

526
01:15:48,333 --> 01:15:49,791
into the rest of the system.

527
01:15:50,125 --> 01:15:51,791
And this really has allowed us to have a

528
01:15:51,791 --> 01:15:52,541
very, very good

529
01:15:52,541 --> 01:15:55,125
understanding of failure scenarios

530
01:15:55,166 --> 01:15:56,916
before our customers even see them.

531
01:15:57,333 --> 01:15:59,750
So these are just general patterns that

532
01:15:59,750 --> 01:16:01,958
are very natural to do

533
01:16:01,958 --> 01:16:02,875
in Effect that we don't

534
01:16:02,916 --> 01:16:05,583
even think about because they actually

535
01:16:05,583 --> 01:16:07,333
don't incur any sort of

536
01:16:07,333 --> 01:16:08,958
additional thinking on our

537
01:16:08,958 --> 01:16:09,333
part.

538
01:16:09,333 --> 01:16:11,083
It's just adding a line

539
01:16:11,083 --> 01:16:12,333
and then it just works.

540
01:16:12,875 --> 01:16:14,166
Yeah, this makes a lot of sense.

541
01:16:14,458 --> 01:16:17,875
I can totally see how reliability is

542
01:16:17,875 --> 01:16:20,250
almost sort of like a emerging factor,

543
01:16:20,416 --> 01:16:22,916
like a second order effect that comes

544
01:16:22,916 --> 01:16:25,541
when you have a composable system,

545
01:16:25,791 --> 01:16:28,791
and when you have observability, when you

546
01:16:28,791 --> 01:16:30,541
can look into what's going on,

547
01:16:30,875 --> 01:16:32,583
when you can eat your

548
01:16:32,583 --> 01:16:34,250
vegetables, then you're healthy.

549
01:16:34,750 --> 01:16:35,291
And so

550
01:16:35,291 --> 01:16:37,583
Building a reliable system is going the

551
01:16:37,583 --> 01:16:39,333
extra mile on all of those things.

552
01:16:39,333 --> 01:16:40,333
This makes a lot of sense.

553
01:16:41,375 --> 01:16:42,416
Given that you built

554
01:16:42,416 --> 01:16:44,541
quite an expansive system,

555
01:16:44,916 --> 01:16:46,875
maybe we can try to break it down a

556
01:16:46,875 --> 01:16:49,083
little bit more with a technical lens on.

557
01:16:49,708 --> 01:16:51,916
So I'm sure that you have

558
01:16:51,916 --> 01:16:53,166
a client side application.

559
01:16:53,291 --> 01:16:54,916
You've mentioned that it's like a single

560
01:16:54,916 --> 01:16:56,500
page app built with Vite,

561
01:16:57,208 --> 01:16:59,083
but more on the backend side.

562
01:16:59,583 --> 01:17:02,041
Can you describe to me what are the

563
01:17:02,041 --> 01:17:04,041
different subcomponents of your system?

564
01:17:04,541 --> 01:17:07,875
Yeah, so in a very simple way, the main

565
01:17:07,875 --> 01:17:09,500
subcomponents here,

566
01:17:09,500 --> 01:17:11,166
there's the application server,

567
01:17:11,166 --> 01:17:12,708
which is essentially an RPC

568
01:17:12,708 --> 01:17:14,541
server that the client

569
01:17:14,541 --> 01:17:15,833
application is speaking with.

570
01:17:15,833 --> 01:17:17,750
Then we have a public API.

571
01:17:18,458 --> 01:17:19,833
So Markprompt is built as

572
01:17:19,833 --> 01:17:21,166
Stripe for customer support,

573
01:17:21,791 --> 01:17:23,375
in the sense that every part of the

574
01:17:23,375 --> 01:17:24,208
system can be

575
01:17:24,208 --> 01:17:26,166
interacted with via our APIs

576
01:17:26,916 --> 01:17:28,708
so that you can actually build deeper

577
01:17:28,708 --> 01:17:29,666
product experiences

578
01:17:29,666 --> 01:17:31,500
inside of your core product.

579
01:17:32,166 --> 01:17:34,208
So we have a public facing API server.

580
01:17:34,208 --> 01:17:37,625
Then we have the ingestion engine, which

581
01:17:37,625 --> 01:17:40,250
takes in all your systems data.

582
01:17:40,250 --> 01:17:41,875
So this can be public facing like a

583
01:17:41,875 --> 01:17:42,833
website that we would

584
01:17:42,833 --> 01:17:44,375
scrape on a regular basis.

585
01:17:44,750 --> 01:17:47,541
It could be GitHub repository or

586
01:17:47,541 --> 01:17:49,250
historical tickets from

587
01:17:49,250 --> 01:17:51,500
Zendesk and Jira and Confluence

588
01:17:51,541 --> 01:17:53,125
and databases from

589
01:17:53,125 --> 01:17:54,750
Salesforce and whatnot.

590
01:17:55,125 --> 01:17:57,458
So we do a bunch of things here.

591
01:17:57,458 --> 01:17:58,291
We import data.

592
01:17:58,291 --> 01:17:58,875
We chunk it up.

593
01:17:58,916 --> 01:18:02,041
We monitor the whole structure of

594
01:18:02,041 --> 01:18:03,333
documents through the AST

595
01:18:03,333 --> 01:18:04,083
and then we build

596
01:18:04,083 --> 01:18:06,000
embeddings for multi-levels.

597
01:18:06,541 --> 01:18:07,291
And then we store them

598
01:18:07,291 --> 01:18:08,166
in a vector database.

599
01:18:08,708 --> 01:18:09,583
And then we have all the

600
01:18:09,583 --> 01:18:11,416
application related servers,

601
01:18:11,416 --> 01:18:13,416
so things like Discord or

602
01:18:13,416 --> 01:18:15,625
Slack or Zendesk and so on,

603
01:18:15,666 --> 01:18:18,541
which are more like simple servers here.

604
01:18:18,541 --> 01:18:18,916
Got it.

605
01:18:18,916 --> 01:18:20,541
Yeah, that makes a lot of sense to break

606
01:18:20,541 --> 01:18:22,000
it up into those different pieces.

607
01:18:22,500 --> 01:18:24,125
I'd actually love to learn a

608
01:18:24,125 --> 01:18:25,333
little bit more about each,

609
01:18:25,791 --> 01:18:26,833
maybe starting with

610
01:18:26,833 --> 01:18:28,083
the application server.

611
01:18:28,333 --> 01:18:29,416
So you mentioned that you're

612
01:18:29,416 --> 01:18:31,166
using Effect RPC in that regard.

613
01:18:31,625 --> 01:18:33,208
What did you use before

614
01:18:33,208 --> 01:18:34,208
you were using Effect?

615
01:18:34,791 --> 01:18:37,500
And what are the qualities of using

616
01:18:37,500 --> 01:18:39,125
Effect for an

617
01:18:39,125 --> 01:18:41,166
application for an RPC server here?

618
01:18:41,958 --> 01:18:42,416
Yeah, sure.

619
01:18:43,000 --> 01:18:44,791
I mean, this before was

620
01:18:44,791 --> 01:18:46,458
just like simple API handlers.

621
01:18:46,750 --> 01:18:48,166
So you would have two

622
01:18:48,166 --> 01:18:51,041
completely decoupled systems.

623
01:18:51,916 --> 01:18:53,333
And now pretty much all the

624
01:18:53,333 --> 01:18:56,041
endpoints are in full RPC.

625
01:18:56,500 --> 01:18:57,958
It starts with a schema, actually.

626
01:18:58,500 --> 01:19:01,375
We define the input schema, the output

627
01:19:01,375 --> 01:19:03,041
schema, and the error schema

628
01:19:03,375 --> 01:19:04,666
for each of these endpoints.

629
01:19:05,250 --> 01:19:07,125
And then it trickles down all the way to

630
01:19:07,125 --> 01:19:07,833
the client application.

631
01:19:08,125 --> 01:19:08,708
So we have this.

632
01:19:09,083 --> 01:19:10,500
Ethan actually wrote this and I hope he's

633
01:19:10,500 --> 01:19:11,208
going to publish it.

634
01:19:11,583 --> 01:19:13,750
Sometimes soon, essentially React query,

635
01:19:13,750 --> 01:19:15,375
but wrapped around with Effect

636
01:19:15,458 --> 01:19:17,541
so that we have the full schema from the

637
01:19:17,541 --> 01:19:18,416
backend all the way to

638
01:19:18,416 --> 01:19:19,375
the client side code.

639
01:19:19,791 --> 01:19:21,791
And we have nothing more to deal with.

640
01:19:21,791 --> 01:19:22,875
So the whole thing is completely

641
01:19:22,875 --> 01:19:24,583
streamlined in terms of the

642
01:19:24,583 --> 01:19:25,916
communication between the client

643
01:19:26,250 --> 01:19:27,375
and the server.

644
01:19:28,125 --> 01:19:28,958
That makes a lot of sense.

645
01:19:29,166 --> 01:19:30,458
And so before you

646
01:19:30,458 --> 01:19:32,208
didn't have any schema layer,

647
01:19:32,833 --> 01:19:35,291
anything to express the kind of data

648
01:19:35,291 --> 01:19:36,958
you're sending across?

649
01:19:37,791 --> 01:19:38,500
No, we didn't actually.

650
01:19:39,375 --> 01:19:39,708
Got it.

651
01:19:39,916 --> 01:19:42,291
Well, I suppose that through the process

652
01:19:42,291 --> 01:19:43,750
of just modeling the schema,

653
01:19:44,458 --> 01:19:46,750
I'm sure that there were a couple of code

654
01:19:46,750 --> 01:19:47,666
paths that you didn't

655
01:19:47,666 --> 01:19:48,833
even account for before.

656
01:19:49,833 --> 01:19:50,583
So the--

657
01:19:50,583 --> 01:19:50,916
Absolutely.

658
01:19:51,750 --> 01:19:55,000
The public API server where you're

659
01:19:55,000 --> 01:19:58,791
exposing an open API spec, I suppose,

660
01:19:59,083 --> 01:20:01,583
how similar or different is that to

661
01:20:01,583 --> 01:20:02,708
your application server?

662
01:20:02,708 --> 01:20:03,958
Can you describe the public

663
01:20:03,958 --> 01:20:05,583
API server setup a bit more?

664
01:20:06,458 --> 01:20:06,875
Yeah, sure.

665
01:20:06,875 --> 01:20:08,333
So this is more of a

666
01:20:08,333 --> 01:20:10,583
standard HTTP server.

667
01:20:10,583 --> 01:20:11,958
This is actually using Effect HTTP.

668
01:20:12,333 --> 01:20:13,416
So again, we have the full--

669
01:20:13,958 --> 01:20:17,000
Everything starts with the Effect runtime

670
01:20:17,000 --> 01:20:18,333
taking over directly

671
01:20:18,333 --> 01:20:19,291
at the request level.

672
01:20:19,916 --> 01:20:20,958
So again, we can model

673
01:20:20,958 --> 01:20:23,083
everything very nicely via schemas.

674
01:20:23,125 --> 01:20:26,291
And one really nice thing of having

675
01:20:26,291 --> 01:20:28,541
everything defined by schemas is

676
01:20:28,708 --> 01:20:30,250
that we can, for instance, automatically

677
01:20:30,250 --> 01:20:31,833
generate the open API spec.

678
01:20:32,250 --> 01:20:34,166
So this is something that we now have

679
01:20:34,166 --> 01:20:35,375
every single endpoint is

680
01:20:35,375 --> 01:20:36,458
automatically documented

681
01:20:37,166 --> 01:20:38,250
just via the schema.

682
01:20:39,208 --> 01:20:39,583
Got it.

683
01:20:39,958 --> 01:20:41,833
How much overlap does your

684
01:20:41,833 --> 01:20:43,458
internal application server,

685
01:20:43,916 --> 01:20:45,500
that RPC server with

686
01:20:45,500 --> 01:20:47,208
the public API server,

687
01:20:47,500 --> 01:20:49,000
does it have a lot of overlap?

688
01:20:49,000 --> 01:20:50,958
Do you reuse a lot of code internally?

689
01:20:51,083 --> 01:20:52,291
Or are those rather

690
01:20:52,291 --> 01:20:54,125
fulfilling different purposes?

691
01:20:54,958 --> 01:20:55,875
They're fulfilling

692
01:20:55,875 --> 01:20:57,458
completely different purposes, yes.

693
01:20:58,625 --> 01:21:00,000
So yeah, I mean, these things are

694
01:21:00,000 --> 01:21:01,541
completely separate.

695
01:21:02,375 --> 01:21:04,000
So to give you one very important

696
01:21:04,000 --> 01:21:07,791
differentiator is that on the RPC server,

697
01:21:07,958 --> 01:21:09,750
we provide permissions.

698
01:21:10,666 --> 01:21:12,875
So you want to make sure that a given

699
01:21:12,875 --> 01:21:14,875
user can perform an action

700
01:21:14,875 --> 01:21:16,000
that they are allowed to.

701
01:21:16,000 --> 01:21:19,791
And so we have a very nice system that

702
01:21:19,791 --> 01:21:21,583
provides the level of

703
01:21:21,583 --> 01:21:23,166
permissions of a user.

704
01:21:23,166 --> 01:21:25,250
This is completely transparent.

705
01:21:25,250 --> 01:21:28,583
We actually used RLS before,

706
01:21:28,583 --> 01:21:29,625
role level security to

707
01:21:29,625 --> 01:21:30,791
enforce these policies.

708
01:21:31,333 --> 01:21:33,333
But there was a real performance impact.

709
01:21:33,541 --> 01:21:34,708
It was just slowing down the crazy,

710
01:21:34,916 --> 01:21:36,958
especially when you're dealing with

711
01:21:36,958 --> 01:21:39,250
hundreds of thousands of data points.

712
01:21:39,500 --> 01:21:41,083
So this had a real impact.

713
01:21:41,333 --> 01:21:42,500
So we got rid of that.

714
01:21:42,791 --> 01:21:43,583
And actually, everything

715
01:21:43,583 --> 01:21:44,875
now is modeled in code.

716
01:21:44,916 --> 01:21:46,666
So the permission, which I guess was

717
01:21:46,666 --> 01:21:48,291
always how things have

718
01:21:48,291 --> 01:21:51,041
been done without RLS.

719
01:21:52,208 --> 01:21:54,333
And so this is, again, an example where

720
01:21:54,333 --> 01:21:56,416
Effect at the type level,

721
01:21:56,416 --> 01:21:58,500
you can immediately spot whether this is

722
01:21:58,500 --> 01:22:00,916
a user that is allowed to

723
01:22:00,916 --> 01:22:02,958
perform a single action,

724
01:22:02,958 --> 01:22:04,125
because that service

725
01:22:04,125 --> 01:22:05,875
requires these sets of permissions.

726
01:22:06,500 --> 01:22:07,333
And so this is very,

727
01:22:07,333 --> 01:22:08,458
very nice to model as well.

728
01:22:09,708 --> 01:22:10,583
That sounds very interesting.

729
01:22:10,583 --> 01:22:13,083
So you've built yourself an internal DSL

730
01:22:13,083 --> 01:22:16,500
to model those permission rules.

731
01:22:16,833 --> 01:22:18,791
Can you explain a little bit more how

732
01:22:18,791 --> 01:22:20,041
that's implemented and how

733
01:22:20,041 --> 01:22:21,833
that can be imagined from

734
01:22:22,500 --> 01:22:23,541
like a type level

735
01:22:23,541 --> 01:22:25,583
perspective or from an API perspective?

736
01:22:26,833 --> 01:22:27,000
Yeah.

737
01:22:27,000 --> 01:22:28,583
I mean, so every user comes

738
01:22:28,583 --> 01:22:30,125
with a set of permissions, right?

739
01:22:30,125 --> 01:22:30,750
And these permissions

740
01:22:30,750 --> 01:22:32,916
can be modeled via types.

741
01:22:33,666 --> 01:22:38,750
And services can declare what level of

742
01:22:38,750 --> 01:22:40,958
permission they required in

743
01:22:40,958 --> 01:22:42,166
order to perform an action.

744
01:22:42,791 --> 01:22:45,041
And so we immediately know if within an

745
01:22:45,041 --> 01:22:47,416
RPC endpoint, we're using a service,

746
01:22:47,666 --> 01:22:48,583
but that the provided

747
01:22:48,583 --> 01:22:51,166
permissions don't match.

748
01:22:52,000 --> 01:22:53,500
Well, then we can flag it.

749
01:22:53,500 --> 01:22:55,083
And so we can guarantee that there's no

750
01:22:55,083 --> 01:22:56,458
code being shipped where

751
01:22:56,458 --> 01:22:57,833
there's an inconsistency here.

752
01:22:59,000 --> 01:22:59,541
I love it.

753
01:22:59,541 --> 01:23:00,500
That sounds very elegant.

754
01:23:00,791 --> 01:23:02,833
I would love to see some code for that.

755
01:23:03,541 --> 01:23:05,708
Could you imagine that there could be a

756
01:23:05,708 --> 01:23:08,833
more commonly reusable package for that?

757
01:23:08,833 --> 01:23:10,750
Or is that only something that makes

758
01:23:10,750 --> 01:23:12,000
sense within your code base?

759
01:23:13,583 --> 01:23:14,250
Good question.

760
01:23:15,916 --> 01:23:18,958
Obviously, we have been just crunching

761
01:23:18,958 --> 01:23:19,666
through this code and

762
01:23:19,666 --> 01:23:20,458
getting into production.

763
01:23:20,666 --> 01:23:23,500
So we haven't thought too much about how

764
01:23:23,500 --> 01:23:24,625
this would extend to a

765
01:23:24,625 --> 01:23:27,166
more generic use case.

766
01:23:27,208 --> 01:23:29,541
But I guess this could be

767
01:23:29,541 --> 01:23:30,625
a very interesting topic.

768
01:23:31,541 --> 01:23:31,750
Right.

769
01:23:31,875 --> 01:23:34,208
Well, anyone in the audience is happily

770
01:23:34,208 --> 01:23:35,666
invited to try to

771
01:23:35,666 --> 01:23:37,083
replicate this by themselves.

772
01:23:37,708 --> 01:23:39,166
Maybe that's even something that we

773
01:23:39,166 --> 01:23:42,041
could, as part of the Effect org, also

774
01:23:42,041 --> 01:23:43,083
look into providing.

775
01:23:43,666 --> 01:23:44,625
To hear you describing

776
01:23:44,625 --> 01:23:46,291
this use case in this DSL,

777
01:23:46,750 --> 01:23:47,541
that makes a lot of

778
01:23:47,541 --> 01:23:48,958
sense for a lot of use cases.

779
01:23:49,958 --> 01:23:52,875
So moving then to the ingestion engine,

780
01:23:53,416 --> 01:23:56,083
can you describe a little bit more of how

781
01:23:56,083 --> 01:23:57,750
that looks like from a

782
01:23:57,750 --> 01:23:58,916
lifecycle perspective?

783
01:23:59,208 --> 01:24:01,000
So you've mentioned the ingestion engine

784
01:24:01,000 --> 01:24:03,958
is mostly meant to bring in data from

785
01:24:03,958 --> 01:24:05,083
various data sources,

786
01:24:05,333 --> 01:24:05,750
whether it's

787
01:24:05,750 --> 01:24:07,458
Salesforce, whether it's Notion.

788
01:24:07,875 --> 01:24:10,625
Walk me through how that works and how

789
01:24:10,625 --> 01:24:13,000
does that work in regards to Effect?

790
01:24:13,000 --> 01:24:14,750
Do you use Effect streams for that?

791
01:24:15,666 --> 01:24:15,875
Yeah.

792
01:24:15,875 --> 01:24:16,541
How does that work?

793
01:24:17,250 --> 01:24:19,208
So it's still pretty bare bones here.

794
01:24:19,208 --> 01:24:20,541
This is something that we have been

795
01:24:20,541 --> 01:24:21,625
discussing also with the

796
01:24:21,625 --> 01:24:23,291
Effect team and the Effect cluster.

797
01:24:23,583 --> 01:24:26,541
This is where we will probably be going.

798
01:24:26,541 --> 01:24:28,958
So now we have our own system, which is

799
01:24:28,958 --> 01:24:31,041
basically just some

800
01:24:31,041 --> 01:24:32,958
long running node servers

801
01:24:32,958 --> 01:24:36,416
that are able to go and fetch the data.

802
01:24:36,708 --> 01:24:39,958
So that could be make a large request to

803
01:24:39,958 --> 01:24:42,583
an SQL database or starting a scraper

804
01:24:42,583 --> 01:24:45,541
that visits a website and when it's done

805
01:24:45,541 --> 01:24:47,625
and purged all the pages,

806
01:24:48,083 --> 01:24:49,958
it is then indexed in a

807
01:24:49,958 --> 01:24:51,750
temporary cache on our side.

808
01:24:52,083 --> 01:24:53,500
And then it goes into the post processing

809
01:24:53,500 --> 01:24:56,458
pipeline, where again, we obviously we

810
01:24:56,458 --> 01:24:57,541
parallelize all this

811
01:24:58,375 --> 01:24:59,708
because every page

812
01:24:59,708 --> 01:25:01,166
needs some post processing.

813
01:25:01,500 --> 01:25:05,500
So we chunk it up and we try to get a

814
01:25:05,500 --> 01:25:06,500
sense of the structure

815
01:25:06,500 --> 01:25:07,583
of the document, the AST,

816
01:25:08,041 --> 01:25:10,166
and then we build these embeddings for

817
01:25:10,166 --> 01:25:12,958
each levels in the AST and

818
01:25:12,958 --> 01:25:14,875
then we store it in a database.

819
01:25:15,666 --> 01:25:17,166
And so the main challenge here is that

820
01:25:17,166 --> 01:25:18,791
these are long running

821
01:25:18,791 --> 01:25:20,500
tasks which can time out,

822
01:25:20,500 --> 01:25:23,708
they can fail and whatnot.

823
01:25:24,291 --> 01:25:26,583
And so now we rely on external systems to

824
01:25:26,583 --> 01:25:28,708
do the whole workflow orchestration,

825
01:25:28,708 --> 01:25:30,083
but this is something where we are going

826
01:25:30,083 --> 01:25:30,916
to be investing some

827
01:25:30,916 --> 01:25:32,250
effort as well because

828
01:25:32,583 --> 01:25:35,708
Effect is the perfect solution here

829
01:25:35,708 --> 01:25:37,250
because we have the full

830
01:25:37,250 --> 01:25:40,125
sets of tools for dealing with

831
01:25:40,250 --> 01:25:41,833
these kinds of situations.

832
01:25:42,958 --> 01:25:45,125
Yeah, I'm really looking forward for

833
01:25:45,125 --> 01:25:46,791
Effect Cluster and Effect

834
01:25:46,791 --> 01:25:48,291
Workflows to mature further.

835
01:25:49,208 --> 01:25:52,583
I think there's more and more use cases,

836
01:25:52,583 --> 01:25:53,500
particularly when it

837
01:25:53,500 --> 01:25:55,250
comes to AI applications

838
01:25:55,666 --> 01:25:56,916
where you want to express

839
01:25:56,916 --> 01:25:59,250
things as long running workflows.

840
01:25:59,916 --> 01:26:02,625
And I think this is where Effect is

841
01:26:02,625 --> 01:26:04,750
really like such a perfect foundation.

842
01:26:05,250 --> 01:26:08,208
So yeah, I think we're going to see some

843
01:26:08,208 --> 01:26:09,416
very interesting updates

844
01:26:09,416 --> 01:26:10,458
throughout the year here.

845
01:26:11,291 --> 01:26:13,083
So stay tuned for that.

846
01:26:13,083 --> 01:26:15,833
Maybe changing gears slightly.

847
01:26:15,833 --> 01:26:17,875
Initially, you've built all of the

848
01:26:17,875 --> 01:26:19,958
system, I think mostly by yourself.

849
01:26:19,958 --> 01:26:21,166
This is where you started

850
01:26:21,166 --> 01:26:22,708
adopting Effect by yourself.

851
01:26:23,333 --> 01:26:25,416
and then later you onboarded other

852
01:26:25,416 --> 01:26:27,250
engineers who didn't have

853
01:26:27,250 --> 01:26:28,791
prior Effect experience.

854
01:26:29,458 --> 01:26:31,416
Can you share a bit more about that

855
01:26:31,416 --> 01:26:33,041
story, how you onboarded

856
01:26:33,041 --> 01:26:34,291
other engineers who didn't

857
01:26:34,291 --> 01:26:36,583
have Effect experience to become

858
01:26:36,583 --> 01:26:38,625
successful working on your code base?

859
01:26:39,208 --> 01:26:39,791
I mean, this is such

860
01:26:39,791 --> 01:26:40,541
an interesting question.

861
01:26:40,625 --> 01:26:44,500
Because you would think that Effect is

862
01:26:44,500 --> 01:26:47,625
mainly for a TypeScript audience.

863
01:26:47,625 --> 01:26:50,750
Web developers who are proficient now in

864
01:26:50,750 --> 01:26:52,458
TypeScript and realize they

865
01:26:52,458 --> 01:26:53,583
need to go to the next level

866
01:26:54,000 --> 01:26:56,958
in terms of building complex systems.

867
01:26:56,958 --> 01:27:00,208
My take here is actually that having a

868
01:27:00,208 --> 01:27:01,916
code base which is already

869
01:27:01,916 --> 01:27:04,750
fully Effect will actually

870
01:27:04,958 --> 01:27:07,958
lower the barrier to entry for people who

871
01:27:07,958 --> 01:27:10,166
have less experience with TypeScript.

872
01:27:10,458 --> 01:27:13,000
So we've seen that with Elliot, our

873
01:27:13,000 --> 01:27:14,000
founding engineer who has

874
01:27:14,000 --> 01:27:15,166
joined a few months ago,

875
01:27:15,666 --> 01:27:17,750
with very little TypeScript experience,

876
01:27:17,750 --> 01:27:20,166
was able to very quickly take

877
01:27:20,166 --> 01:27:21,625
it up and then be productive.

878
01:27:22,375 --> 01:27:23,916
We've run some trials with some

879
01:27:23,916 --> 01:27:26,000
candidates in the last few weeks with,

880
01:27:26,541 --> 01:27:27,875
again, little experience in

881
01:27:27,875 --> 01:27:28,250
TypeScript.

882
01:27:28,250 --> 01:27:30,250
The thing is that we are hiring a lot of

883
01:27:30,250 --> 01:27:32,416
machine learning engineers.

884
01:27:32,541 --> 01:27:35,208
And so they have typically already a lot

885
01:27:35,208 --> 01:27:36,625
of experience with more

886
01:27:36,625 --> 01:27:37,416
of the machine learning

887
01:27:37,833 --> 01:27:39,000
sets of tools like Python

888
01:27:39,000 --> 01:27:41,541
and very little on TypeScript.

889
01:27:41,541 --> 01:27:44,250
But what we have seen is onboarding them

890
01:27:44,250 --> 01:27:45,583
on our code base, they

891
01:27:45,583 --> 01:27:46,541
were actually able to be

892
01:27:46,541 --> 01:27:47,875
very productive, very early on.

893
01:27:48,166 --> 01:27:50,583
And the great thing is that there's not

894
01:27:50,583 --> 01:27:51,916
much room for bad

895
01:27:51,916 --> 01:27:53,333
practice or the kinds of things

896
01:27:53,333 --> 01:27:55,250
that you need to learn when you get

897
01:27:55,250 --> 01:27:56,541
started with a new language.

898
01:27:56,583 --> 01:27:58,458
So what I think is that actually

899
01:27:58,458 --> 01:27:59,500
Effect will

900
01:27:59,500 --> 01:28:02,375
allow them to be proficient and

901
01:28:02,375 --> 01:28:03,416
build very reliable

902
01:28:03,416 --> 01:28:05,083
code within a few weeks.

903
01:28:05,625 --> 01:28:07,541
If it had not been an Effect and more

904
01:28:07,541 --> 01:28:08,625
like vanilla TypeScript,

905
01:28:08,833 --> 01:28:09,958
yes, sure, there's fewer

906
01:28:09,958 --> 01:28:10,708
things to learn.

907
01:28:10,708 --> 01:28:12,125
It's kind of easy and so on.

908
01:28:12,625 --> 01:28:15,041
But you would build up this understanding

909
01:28:15,041 --> 01:28:16,458
and intuition for the

910
01:28:16,458 --> 01:28:17,458
language over the course of

911
01:28:17,458 --> 01:28:17,875
years.

912
01:28:18,083 --> 01:28:18,333
Right.

913
01:28:18,333 --> 01:28:19,791
And then within years, you'll be able to

914
01:28:19,791 --> 01:28:21,791
build very complex and

915
01:28:21,791 --> 01:28:23,083
reliable systems because you

916
01:28:23,125 --> 01:28:26,375
have been proficient in the language.

917
01:28:26,875 --> 01:28:29,833
So Effect gives you these guardrails that

918
01:28:29,833 --> 01:28:31,250
with the whole thing is

919
01:28:31,250 --> 01:28:32,291
in Effect, sure, you need

920
01:28:32,291 --> 01:28:33,333
to understand the

921
01:28:33,333 --> 01:28:35,208
whole catalog of things.

922
01:28:35,208 --> 01:28:36,291
And this you just take up

923
01:28:36,291 --> 01:28:37,541
as you have new use cases.

924
01:28:37,916 --> 01:28:39,500
But if you have a really good foundation,

925
01:28:39,875 --> 01:28:41,125
like the full RPC

926
01:28:41,125 --> 01:28:43,041
server, you basically just

927
01:28:43,166 --> 01:28:45,166
you start writing schema, right?

928
01:28:45,166 --> 01:28:46,583
You write a schema and then

929
01:28:46,583 --> 01:28:48,041
you fit it into the system.

930
01:28:48,541 --> 01:28:50,625
And then once it's there, it's done.

931
01:28:51,125 --> 01:28:52,458
You don't need to change it.

932
01:28:52,500 --> 01:28:54,125
You haven't done anything bad

933
01:28:54,125 --> 01:28:56,000
or anything that will break.

934
01:28:56,250 --> 01:28:56,458
Right.

935
01:28:56,541 --> 01:28:59,041
So my take on this is that actually it

936
01:28:59,041 --> 01:29:00,041
might actually have the

937
01:29:00,041 --> 01:29:01,708
opposite effect of what

938
01:29:01,708 --> 01:29:03,958
we would expect, which is to be able to

939
01:29:03,958 --> 01:29:06,375
onboard non TypeScript

940
01:29:06,375 --> 01:29:08,958
engineers much, much faster.

941
01:29:09,375 --> 01:29:11,000
Yeah, that definitely sounds

942
01:29:11,000 --> 01:29:12,333
a little bit counterintuitive.

943
01:29:12,458 --> 01:29:15,375
And the first time I heard about this

944
01:29:15,375 --> 01:29:16,333
anecdote, and you shared

945
01:29:16,333 --> 01:29:17,791
this privately with me before,

946
01:29:18,416 --> 01:29:21,500
and that person you've just mentioned,

947
01:29:21,500 --> 01:29:23,833
Elliot, gave a brilliant talk at the last

948
01:29:23,916 --> 01:29:26,333
Effect Meetup in San Francisco where he

949
01:29:26,333 --> 01:29:28,333
shared his first hand

950
01:29:28,333 --> 01:29:29,750
experience learning Effect.

951
01:29:30,500 --> 01:29:32,125
And yeah, I think that is a

952
01:29:32,125 --> 01:29:33,166
little bit counterintuitive.

953
01:29:33,291 --> 01:29:35,166
But when you think about it more, it

954
01:29:35,166 --> 01:29:37,791
makes a lot of sense because most

955
01:29:37,791 --> 01:29:39,250
experienced TypeScript

956
01:29:39,291 --> 01:29:42,541
engineers over years, they had to first

957
01:29:42,541 --> 01:29:44,375
learn how to do anything

958
01:29:44,375 --> 01:29:46,458
with TypeScript at all and then

959
01:29:46,500 --> 01:29:49,958
later learn to ignore like those 80 paths

960
01:29:49,958 --> 01:29:52,125
out of 100 how you could do

961
01:29:52,125 --> 01:29:53,166
something with TypeScript,

962
01:29:53,416 --> 01:29:54,500
but that will lead you

963
01:29:54,500 --> 01:29:55,958
down a dangerous road.

964
01:29:56,500 --> 01:29:58,833
Whereas Effect constrains you a little

965
01:29:58,833 --> 01:30:01,208
bit more and puts you on a

966
01:30:01,208 --> 01:30:02,791
path to success in a way.

967
01:30:03,708 --> 01:30:04,875
That's also like it has been my

968
01:30:04,875 --> 01:30:06,666
experience for I think for me

969
01:30:06,666 --> 01:30:08,875
coming more from TypeScript,

970
01:30:09,916 --> 01:30:12,500
I had to unlearn a lot of things how I

971
01:30:12,500 --> 01:30:14,041
used to do things in TypeScript before.

972
01:30:14,708 --> 01:30:17,375
But this is where for me, a good

973
01:30:17,375 --> 01:30:19,416
foundation to pick up Effect

974
01:30:19,416 --> 01:30:21,791
was actually dabbling in other

975
01:30:21,791 --> 01:30:24,541
languages such as Swift and Rust, where I

976
01:30:24,541 --> 01:30:28,750
already primed my mind more on more saner

977
01:30:29,250 --> 01:30:31,708
engineering practices and learning the

978
01:30:31,708 --> 01:30:33,208
right habits and

979
01:30:33,208 --> 01:30:34,875
embracing the right abstractions.

980
01:30:35,583 --> 01:30:38,041
And so I can totally see how someone who

981
01:30:38,041 --> 01:30:39,708
doesn't have prior TypeScript experience

982
01:30:40,166 --> 01:30:42,375
maybe experience in other languages,

983
01:30:42,375 --> 01:30:45,666
which have more appropriate primitives

984
01:30:45,833 --> 01:30:48,083
can be up and running with Effect in no

985
01:30:48,083 --> 01:30:50,125
time. That is amazing to hear.

986
01:30:50,666 --> 01:30:53,125
So can you walk me through a little bit

987
01:30:53,125 --> 01:30:54,583
more through the process

988
01:30:54,583 --> 01:30:56,250
how you went tactically

989
01:30:56,416 --> 01:31:00,291
about migrating the code base as it was

990
01:31:00,291 --> 01:31:02,041
before Effect one by one

991
01:31:02,041 --> 01:31:03,500
step at a time to migrating

992
01:31:03,750 --> 01:31:06,833
it to Effect. Rome wasn't conquered in a

993
01:31:06,833 --> 01:31:08,250
day, so wasn't your code

994
01:31:08,250 --> 01:31:09,750
base. So how did you go about it?

995
01:31:10,041 --> 01:31:12,083
We had some great help. And this is where

996
01:31:12,083 --> 01:31:13,375
I think the Effect community

997
01:31:13,375 --> 01:31:15,458
is such a wonderful community

998
01:31:15,458 --> 01:31:19,875
of people who are nice and helpful. You

999
01:31:19,875 --> 01:31:22,541
kicked it off with us. So we've been

1000
01:31:22,541 --> 01:31:25,541
this for years. And immediately I saw the

1001
01:31:25,541 --> 01:31:27,291
importance of this, but

1002
01:31:27,291 --> 01:31:29,666
never found the time to

1003
01:31:30,250 --> 01:31:32,666
actually learn how to do it in practice.

1004
01:31:32,666 --> 01:31:33,458
I think this is also

1005
01:31:33,458 --> 01:31:34,625
maybe related to the lack of

1006
01:31:34,625 --> 01:31:36,375
documentation and concrete examples back

1007
01:31:36,375 --> 01:31:37,125
in the day. How do you

1008
01:31:37,125 --> 01:31:38,625
actually convert an API

1009
01:31:38,666 --> 01:31:41,750
endpoint to Effect? How do you just do

1010
01:31:41,750 --> 01:31:43,666
it? So I think this little

1011
01:31:43,666 --> 01:31:45,041
catalyzer was really important,

1012
01:31:45,666 --> 01:31:49,625
which allowed us, our team, to then get a

1013
01:31:49,625 --> 01:31:50,708
sense of where we could

1014
01:31:50,708 --> 01:31:52,125
start fitting it in. It was still

1015
01:31:52,125 --> 01:31:53,958
like very, very new. This was earlier

1016
01:31:53,958 --> 01:31:57,375
last year. And then we had the pleasure

1017
01:31:57,375 --> 01:31:59,000
of having Ethan with

1018
01:31:59,000 --> 01:32:01,625
us over the summer. And he wrote a lot of

1019
01:32:01,625 --> 01:32:03,041
very important code for both

1020
01:32:03,041 --> 01:32:04,333
the backend side of things,

1021
01:32:05,166 --> 01:32:08,250
schema, the database, the React query

1022
01:32:08,250 --> 01:32:10,125
part, which put us in a

1023
01:32:10,125 --> 01:32:11,000
really good foundation.

1024
01:32:11,500 --> 01:32:13,875
We had most of it basically sketched out.

1025
01:32:14,500 --> 01:32:17,791
And then in September, we decided to

1026
01:32:18,125 --> 01:32:20,083
do a big, big push and just get

1027
01:32:20,083 --> 01:32:23,166
everything migrated. So this was like a

1028
01:32:23,166 --> 01:32:23,833
bit slow in the beginning.

1029
01:32:24,500 --> 01:32:27,583
And then very, very quickly, within a few

1030
01:32:27,583 --> 01:32:28,583
weeks, we had the

1031
01:32:28,583 --> 01:32:31,375
whole thing migrated over.

1032
01:32:32,125 --> 01:32:34,291
Good. That makes a lot of sense. And

1033
01:32:34,291 --> 01:32:36,875
happy to have acted as

1034
01:32:36,875 --> 01:32:38,291
a little catalyst here,

1035
01:32:38,750 --> 01:32:40,833
but you've picked up everything so

1036
01:32:40,833 --> 01:32:43,791
quickly. So I think this was rather a

1037
01:32:43,791 --> 01:32:45,625
little bit of giving you

1038
01:32:45,875 --> 01:32:48,791
more courage to go this way. And I think

1039
01:32:48,791 --> 01:32:50,625
you figured out quickly

1040
01:32:50,625 --> 01:32:52,916
how to work with everything,

1041
01:32:53,291 --> 01:32:57,416
and you migrated everything in no time. I

1042
01:32:57,416 --> 01:32:58,875
would say, honestly,

1043
01:32:59,500 --> 01:33:00,583
the important thing is the

1044
01:33:00,583 --> 01:33:03,958
catalyzer here. Once you have the starter

1045
01:33:03,958 --> 01:33:05,875
blocks, then it's quite easy to

1046
01:33:05,875 --> 01:33:07,291
generalize. It's more

1047
01:33:07,291 --> 01:33:09,208
like where do you start? And the

1048
01:33:09,208 --> 01:33:10,666
documentation obviously is much better

1049
01:33:10,666 --> 01:33:11,625
now. So I think this is

1050
01:33:11,666 --> 01:33:14,041
a great thing. But I think this little

1051
01:33:14,041 --> 01:33:17,125
initial nudge is

1052
01:33:17,125 --> 01:33:18,458
what made the difference here.

1053
01:33:19,875 --> 01:33:22,250
If you think about your system as sort of

1054
01:33:22,250 --> 01:33:27,083
like a tree of different subsystems,

1055
01:33:27,416 --> 01:33:29,291
you can go about converting an existing

1056
01:33:29,291 --> 01:33:31,458
system to Effect in different ways.

1057
01:33:31,458 --> 01:33:33,875
Either you go first for

1058
01:33:33,875 --> 01:33:36,083
the leaves, and then you go up one step

1059
01:33:36,083 --> 01:33:37,583
at a time until your entire

1060
01:33:37,583 --> 01:33:39,375
program, your entire system is

1061
01:33:39,416 --> 01:33:41,875
refactored with Effect. But you can also

1062
01:33:41,875 --> 01:33:44,375
isolate specific sub nodes

1063
01:33:44,375 --> 01:33:47,791
and from the outside call the

1064
01:33:47,791 --> 01:33:50,208
effect and inside of it call other

1065
01:33:50,208 --> 01:33:52,250
things that are not yet Effect with

1066
01:33:52,250 --> 01:33:54,833
Effect.runPromise or

1067
01:33:54,833 --> 01:33:57,666
effect dot promise to run some effects,

1068
01:33:57,875 --> 01:33:59,708
some non-effect code yet.

1069
01:34:00,166 --> 01:34:02,208
Did you find any particular

1070
01:34:02,375 --> 01:34:06,250
topology adoption strategy for you to be

1071
01:34:06,250 --> 01:34:08,916
working well? So did you go first

1072
01:34:08,916 --> 01:34:11,500
all for the leaves? Or did you go

1073
01:34:11,500 --> 01:34:12,666
wherever you wanted to

1074
01:34:12,666 --> 01:34:14,958
refactor something anyway? How did you

1075
01:34:14,958 --> 01:34:17,791
go about the decision process of when to

1076
01:34:17,791 --> 01:34:19,208
refactor what with Effect?

1077
01:34:19,791 --> 01:34:20,666
Well, yeah, it was the leaves in

1078
01:34:20,708 --> 01:34:24,250
the beginning. And then it was the top

1079
01:34:24,250 --> 01:34:26,208
down afterwards, because

1080
01:34:26,208 --> 01:34:27,291
we just realized that this

1081
01:34:27,291 --> 01:34:29,750
was what we needed. And we just needed as

1082
01:34:29,750 --> 01:34:31,750
quickly as possible. So

1083
01:34:31,750 --> 01:34:33,500
then there was a combined push

1084
01:34:34,000 --> 01:34:36,458
from the whole team to just get the

1085
01:34:36,458 --> 01:34:37,791
migration done as quickly as

1086
01:34:37,791 --> 01:34:40,500
possible. So the RPC was written

1087
01:34:40,500 --> 01:34:43,166
really like top down, right? Because,

1088
01:34:43,166 --> 01:34:44,750
well top down in the

1089
01:34:44,750 --> 01:34:46,666
sense that one route would be

1090
01:34:47,000 --> 01:34:49,833
migrated to RPC, Effect RPC, then another

1091
01:34:49,833 --> 01:34:52,333
one and so on. But for

1092
01:34:52,333 --> 01:34:53,625
sure, this is a nice thing with

1093
01:34:53,625 --> 01:34:55,125
Effect is that you can do it on the

1094
01:34:55,125 --> 01:34:57,208
leave to start with and you're not

1095
01:34:57,208 --> 01:34:58,083
touching anything else

1096
01:34:58,333 --> 01:35:00,208
of your code base. But yeah, you

1097
01:35:00,208 --> 01:35:01,666
definitely feel the urge to

1098
01:35:01,666 --> 01:35:05,250
get the whole thing end to end.

1099
01:35:05,625 --> 01:35:08,250
The runtime should be initiated at the

1100
01:35:08,250 --> 01:35:10,416
very beginning of the

1101
01:35:10,416 --> 01:35:11,625
thing, right? So that you have

1102
01:35:11,666 --> 01:35:14,708
the full happy path, because you get to

1103
01:35:14,708 --> 01:35:16,541
love the happy path here, right?

1104
01:35:16,541 --> 01:35:18,625
Nice. So if I remember

1105
01:35:18,625 --> 01:35:20,833
correctly, I think it's now been pretty

1106
01:35:20,833 --> 01:35:22,750
much a year since you've been using

1107
01:35:22,750 --> 01:35:24,000
Effect in production.

1108
01:35:24,666 --> 01:35:26,125
looking back, what were some

1109
01:35:26,125 --> 01:35:27,666
of the things that were

1110
01:35:27,666 --> 01:35:30,000
like unexpectedly good with

1111
01:35:30,000 --> 01:35:32,041
Effect and also some things that were

1112
01:35:32,041 --> 01:35:33,791
more challenging that you thought or

1113
01:35:33,791 --> 01:35:35,333
unexpected in some ways?

1114
01:35:36,583 --> 01:35:39,083
I didn't expect the Schema package

1115
01:35:39,083 --> 01:35:42,000
to be, you know, I didn't have any

1116
01:35:42,000 --> 01:35:43,375
expectations that this

1117
01:35:43,375 --> 01:35:45,875
was really a core thing. In fact, because

1118
01:35:45,875 --> 01:35:49,375
this is really wonderful, how you can

1119
01:35:49,375 --> 01:35:50,708
control both like the

1120
01:35:50,875 --> 01:35:53,500
decoding part, the encoding part, how you

1121
01:35:53,500 --> 01:35:54,875
can pipe everything

1122
01:35:54,875 --> 01:35:59,333
together. This is one of the sort of,

1123
01:36:00,125 --> 01:36:01,916
it shifts away how you think about a

1124
01:36:01,916 --> 01:36:02,875
problem. Because usually,

1125
01:36:03,375 --> 01:36:05,375
now when I think of a problem,

1126
01:36:05,375 --> 01:36:06,458
I start thinking about what is the

1127
01:36:06,458 --> 01:36:07,750
schema, right? It is very

1128
01:36:07,750 --> 01:36:09,833
different from what is the actual

1129
01:36:09,875 --> 01:36:11,708
application code. You redesign your

1130
01:36:11,708 --> 01:36:13,916
schema, you think, well, how should it

1131
01:36:13,916 --> 01:36:16,000
transform the data here?

1132
01:36:16,416 --> 01:36:18,791
And then you work your way up to getting

1133
01:36:18,791 --> 01:36:21,583
it all the way in your

1134
01:36:21,583 --> 01:36:23,250
code. So I think that schema was

1135
01:36:23,250 --> 01:36:24,833
a very, very positive,

1136
01:36:24,833 --> 01:36:26,791
unexpected thing that came out of this.

1137
01:36:27,708 --> 01:36:28,291
To give you an example,

1138
01:36:29,083 --> 01:36:32,875
I always wanted to, again, in the quest

1139
01:36:32,875 --> 01:36:34,833
for extreme lining and being

1140
01:36:34,833 --> 01:36:36,291
as efficient as possible as a

1141
01:36:36,291 --> 01:36:39,375
startup, things like documentation, I

1142
01:36:39,375 --> 01:36:41,416
care a lot about documentation. And the

1143
01:36:41,416 --> 01:36:42,250
more we can put that

1144
01:36:42,250 --> 01:36:44,875
on like autopilot, the better, right? So

1145
01:36:44,875 --> 01:36:46,041
the ability to take

1146
01:36:46,041 --> 01:36:47,250
your public API endpoints,

1147
01:36:47,958 --> 01:36:49,833
and the other schemas generate an open

1148
01:36:49,833 --> 01:36:52,458
API spec is exactly the kind of things

1149
01:36:52,458 --> 01:36:54,708
that you want, right?

1150
01:36:54,708 --> 01:36:57,250
So this was a very, very nice discovery.

1151
01:36:57,791 --> 01:36:59,291
Right. That makes a lot of

1152
01:36:59,291 --> 01:37:00,583
sense. And I think that goes

1153
01:37:00,666 --> 01:37:04,000
hand in hand with what I've also found in

1154
01:37:04,000 --> 01:37:06,375
my development practices over the years,

1155
01:37:06,833 --> 01:37:10,083
is that I always started to think more

1156
01:37:10,083 --> 01:37:13,000
about the types of a system.

1157
01:37:13,000 --> 01:37:13,875
That's like typically what I

1158
01:37:13,916 --> 01:37:16,541
start out with. I just like described the

1159
01:37:16,541 --> 01:37:18,416
types. But then I've also

1160
01:37:18,416 --> 01:37:20,000
found myself thinking about,

1161
01:37:20,208 --> 01:37:22,708
actually, this data of this particular

1162
01:37:22,708 --> 01:37:25,291
type doesn't just live inside of this

1163
01:37:25,291 --> 01:37:26,291
boundary of the system,

1164
01:37:26,625 --> 01:37:29,416
but it needs to move across network

1165
01:37:29,416 --> 01:37:31,416
boundaries, across threat boundaries,

1166
01:37:31,416 --> 01:37:33,333
etc. And now you're,

1167
01:37:33,333 --> 01:37:35,541
you need to serialize, deserialize that

1168
01:37:35,541 --> 01:37:38,250
variable. And this is where

1169
01:37:38,250 --> 01:37:40,916
schemas come in. So I ended up

1170
01:37:40,916 --> 01:37:43,333
doing exactly the same as you. Like I

1171
01:37:43,333 --> 01:37:44,541
start thinking about like,

1172
01:37:44,541 --> 01:37:46,291
okay, what data am I dealing

1173
01:37:46,291 --> 01:37:49,125
with here? And I modeled it as schemas

1174
01:37:49,125 --> 01:37:50,541
and derived the types from it.

1175
01:37:51,500 --> 01:37:53,625
And well, we see this here as

1176
01:37:53,625 --> 01:37:56,416
like a big revelation turns out in other

1177
01:37:56,416 --> 01:37:58,250
programming languages, that's what you

1178
01:37:58,250 --> 01:37:59,833
always do. When you have

1179
01:37:59,833 --> 01:38:02,250
like in Rust, etc. When you have like a

1180
01:38:02,250 --> 01:38:03,500
struct definition, you can

1181
01:38:03,500 --> 01:38:06,250
derive schemas from it. But

1182
01:38:06,250 --> 01:38:08,416
I think for TypeScript, this is really

1183
01:38:08,416 --> 01:38:10,166
for most engineers, that's

1184
01:38:10,166 --> 01:38:12,458
something novel. And I think

1185
01:38:12,458 --> 01:38:14,708
this is a pattern that should be embraced

1186
01:38:14,708 --> 01:38:16,291
much more since I think

1187
01:38:16,291 --> 01:38:18,625
default is you just ignore

1188
01:38:18,875 --> 01:38:21,208
the existence of a schema and you JSON

1189
01:38:21,208 --> 01:38:23,416
stringify everything. And then you're

1190
01:38:23,416 --> 01:38:25,041
surprised what happens

1191
01:38:25,041 --> 01:38:27,791
to your classes or to your dates. So

1192
01:38:27,791 --> 01:38:29,916
yeah, that schema is such

1193
01:38:29,916 --> 01:38:31,708
an integral part of Effect,

1194
01:38:32,208 --> 01:38:34,916
I think is no coincidence. And I'm very

1195
01:38:34,916 --> 01:38:36,708
happy that it gets so

1196
01:38:36,708 --> 01:38:37,916
much attention for detail.

1197
01:38:38,666 --> 01:38:41,125
Yeah, I mean, I would say it's not only

1198
01:38:41,125 --> 01:38:42,125
the fact that you have like

1199
01:38:42,125 --> 01:38:44,666
decoding and encoding and so

1200
01:38:44,666 --> 01:38:48,083
on, it's the fact that it's so much in

1201
01:38:48,083 --> 01:38:49,750
harmony with the rest of

1202
01:38:49,750 --> 01:38:51,333
the whole like Effect way of

1203
01:38:51,333 --> 01:38:55,958
doing things, right? So it just feels so,

1204
01:38:55,958 --> 01:38:57,916
you know, an integral

1205
01:38:57,916 --> 01:38:59,750
part of effect itself.

1206
01:38:59,958 --> 01:39:04,166
Yeah, I fully agree. So in regards to the

1207
01:39:04,166 --> 01:39:05,666
more challenging aspects,

1208
01:39:06,166 --> 01:39:08,166
what were some of the challenges that you

1209
01:39:08,166 --> 01:39:10,416
found working in an Effect code base?

1210
01:39:11,333 --> 01:39:14,625
Sure. I would say it can give you a sense

1211
01:39:14,625 --> 01:39:17,166
of, you know

1212
01:39:17,166 --> 01:39:17,916
maybe a

1213
01:39:17,916 --> 01:39:18,958
false sense of security.

1214
01:39:19,333 --> 01:39:20,833
Because you think that everything

1215
01:39:20,833 --> 01:39:21,916
is dealt with at the

1216
01:39:21,916 --> 01:39:23,458
type level and you get no

1217
01:39:23,458 --> 01:39:26,208
flagged of compile time errors and so on.

1218
01:39:26,833 --> 01:39:28,208
And this is partly

1219
01:39:28,208 --> 01:39:30,416
true. But I think it's very,

1220
01:39:30,416 --> 01:39:33,041
very important. It's very important to

1221
01:39:33,041 --> 01:39:34,375
understand that this is not

1222
01:39:34,375 --> 01:39:36,666
the case. And it gives you

1223
01:39:36,833 --> 01:39:39,625
really good like foundation, but you're

1224
01:39:39,625 --> 01:39:44,291
not exempt of or die or catch all that

1225
01:39:44,291 --> 01:39:46,833
was put at the end of

1226
01:39:46,833 --> 01:39:48,958
your pipes. And so all the other errors

1227
01:39:48,958 --> 01:39:52,083
in between are, you know, just you don't

1228
01:39:52,083 --> 01:39:52,875
see them. And we had

1229
01:39:52,875 --> 01:39:55,625
an example where we had this

1230
01:39:55,625 --> 01:39:56,750
bug in our code base, and it

1231
01:39:56,750 --> 01:39:58,708
was quite hard to figure out

1232
01:39:59,291 --> 01:40:01,416
where it went wrong. So I think this is

1233
01:40:01,416 --> 01:40:02,500
something that, you know,

1234
01:40:02,666 --> 01:40:03,875
Effect is a very, very powerful

1235
01:40:03,875 --> 01:40:08,166
tool. And it brings out the best in us,

1236
01:40:08,166 --> 01:40:09,833
you know, engineers, I think.

1237
01:40:10,250 --> 01:40:12,041
But it also needs to be

1238
01:40:12,041 --> 01:40:15,708
dealt with knowing that, you know,

1239
01:40:15,708 --> 01:40:17,708
it's not like a safety guard

1240
01:40:17,708 --> 01:40:19,208
or anything, you can mess up

1241
01:40:19,250 --> 01:40:21,916
and you can do things that are very hard

1242
01:40:21,916 --> 01:40:23,666
to then investigate because

1243
01:40:23,666 --> 01:40:24,666
you've built up this, this

1244
01:40:24,666 --> 01:40:26,125
sense of everything is just working

1245
01:40:26,125 --> 01:40:28,458
smoothly. So this is one thing I think

1246
01:40:28,458 --> 01:40:30,416
that this is as important

1247
01:40:30,416 --> 01:40:32,250
to keep in mind when you're building, you

1248
01:40:32,250 --> 01:40:34,041
know, on top of Effect. I

1249
01:40:34,041 --> 01:40:35,375
think another thing that it gets,

1250
01:40:35,708 --> 01:40:38,166
a little bit hard to track is,

1251
01:40:38,166 --> 01:40:39,333
dependency

1252
01:40:39,333 --> 01:40:41,083
injection is just wonderful,

1253
01:40:42,166 --> 01:40:43,958
in Effect. And I think that's, that's, I

1254
01:40:43,958 --> 01:40:44,708
would mention this probably

1255
01:40:44,708 --> 01:40:46,166
as the second most important,

1256
01:40:46,625 --> 01:40:48,500
discovery or delight of

1257
01:40:48,500 --> 01:40:50,750
working with Effect. But,

1258
01:40:50,750 --> 01:40:53,291
you know, where do you put your

1259
01:40:53,291 --> 01:40:55,083
dependency? Where is it in your code? How

1260
01:40:55,083 --> 01:40:56,458
do you like chase the

1261
01:40:56,458 --> 01:40:58,166
dependency, you know, the service

1262
01:40:58,333 --> 01:41:01,333
that you provided, that is now affecting

1263
01:41:01,333 --> 01:41:02,666
a completely different

1264
01:41:02,666 --> 01:41:03,666
part of your code base,

1265
01:41:03,958 --> 01:41:05,208
that might be, you

1266
01:41:05,208 --> 01:41:06,166
know, some some tooling

1267
01:41:06,166 --> 01:41:07,291
to build inside of the

1268
01:41:07,791 --> 01:41:10,458
IDE itself, to be able to make it easy to

1269
01:41:10,458 --> 01:41:11,875
spot the connection, right.

1270
01:41:12,541 --> 01:41:13,958
But now we still like in this

1271
01:41:13,958 --> 01:41:15,833
very barebone situation where it's kind

1272
01:41:15,833 --> 01:41:17,041
of hard to understand

1273
01:41:17,041 --> 01:41:20,166
exactly, you know, the hierarchy of

1274
01:41:20,166 --> 01:41:23,125
your dependencies, right, and where they

1275
01:41:23,125 --> 01:41:24,375
are actually being used

1276
01:41:24,375 --> 01:41:26,208
in your code. So it can be

1277
01:41:26,208 --> 01:41:27,708
a little bit hard to navigate sometimes.

1278
01:41:28,791 --> 01:41:29,833
Right. Yeah, I found that

1279
01:41:29,833 --> 01:41:31,541
myself as well in the project

1280
01:41:31,541 --> 01:41:34,125
I'm working on. And it is actually

1281
01:41:34,125 --> 01:41:35,125
something that we're thinking

1282
01:41:35,125 --> 01:41:37,416
about, that we could possibly

1283
01:41:37,791 --> 01:41:41,958
enhance through a IDE integration, etc.

1284
01:41:41,958 --> 01:41:44,041
So stay, stay tuned for

1285
01:41:44,041 --> 01:41:46,125
for that. You said something

1286
01:41:46,666 --> 01:41:48,833
interesting just before, where you said

1287
01:41:48,833 --> 01:41:50,583
effect brings out the

1288
01:41:50,583 --> 01:41:53,208
best in us engineers. Can you

1289
01:41:53,208 --> 01:41:55,500
elaborate on that? What do you mean by that

1290
01:41:55,500 --> 01:41:58,125
Well, as an engineer,

1291
01:41:58,125 --> 01:41:58,958
you want to build features,

1292
01:41:59,125 --> 01:42:00,583
you want to build like real robust

1293
01:42:00,583 --> 01:42:03,041
systems, you want to spend

1294
01:42:03,041 --> 01:42:05,375
ideally all your time doing

1295
01:42:05,375 --> 01:42:08,083
that. You don't want to spend your time

1296
01:42:08,083 --> 01:42:10,125
fighting the language, fighting, you

1297
01:42:10,125 --> 01:42:11,375
know, building something

1298
01:42:11,458 --> 01:42:13,458
that you know, the language was not meant

1299
01:42:13,458 --> 01:42:14,208
for, to give you an

1300
01:42:14,208 --> 01:42:15,333
example, like concurrency and

1301
01:42:15,333 --> 01:42:17,000
TypeScript, right, these are things that

1302
01:42:17,000 --> 01:42:21,125
you know, you want a way to,

1303
01:42:21,125 --> 01:42:22,916
you know, build a concurrent

1304
01:42:22,916 --> 01:42:25,416
system, where you're thinking about what

1305
01:42:25,416 --> 01:42:26,458
is the system actually doing

1306
01:42:26,458 --> 01:42:28,000
rather than like setting up

1307
01:42:28,000 --> 01:42:30,958
all the boilerplate in order to have that

1308
01:42:30,958 --> 01:42:34,458
system in place. So I would

1309
01:42:34,458 --> 01:42:36,500
say Effect really gives you

1310
01:42:36,916 --> 01:42:40,041
the right premise. So one thing I'm

1311
01:42:40,041 --> 01:42:42,000
thinking about is, now that we've

1312
01:42:42,000 --> 01:42:43,125
completed this migration,

1313
01:42:44,666 --> 01:42:46,375
the full migration, it kind of feels like

1314
01:42:46,375 --> 01:42:48,500
this is the end game. I know

1315
01:42:48,500 --> 01:42:49,708
this might sound a bit like

1316
01:42:50,250 --> 01:42:54,125
naive or unrealistic, but it kind of

1317
01:42:54,125 --> 01:42:56,083
feels like more stable.

1318
01:42:56,333 --> 01:42:58,125
And at least if we continue

1319
01:42:58,541 --> 01:43:00,166
building our code base on TypeScript with

1320
01:43:00,166 --> 01:43:02,208
Effect, it doesn't feel

1321
01:43:02,208 --> 01:43:03,166
like we're going to spend

1322
01:43:04,250 --> 01:43:06,666
many more like cycles, like refactoring

1323
01:43:06,666 --> 01:43:09,000
the code, right, it feels

1324
01:43:09,000 --> 01:43:11,166
like this sort of timeless,

1325
01:43:12,166 --> 01:43:14,833
like code base now now now it's, it's,

1326
01:43:14,833 --> 01:43:16,125
it's there. Effect is

1327
01:43:16,125 --> 01:43:17,791
going to evolve, our code base is

1328
01:43:17,791 --> 01:43:19,416
going to evolve. It feels like this is

1329
01:43:19,416 --> 01:43:20,583
going to be like adjustments

1330
01:43:20,583 --> 01:43:22,000
and not like a full rewrite.

1331
01:43:22,250 --> 01:43:24,208
And this is what I mean by, you know, it

1332
01:43:24,208 --> 01:43:25,583
feels like kind of like

1333
01:43:25,583 --> 01:43:26,958
building a house with some really

1334
01:43:27,000 --> 01:43:29,583
good like walls and floor and ceiling and

1335
01:43:29,583 --> 01:43:31,416
so on. It's just there now.

1336
01:43:32,041 --> 01:43:34,083
And this is what we are all

1337
01:43:34,083 --> 01:43:36,500
I guess, striving for as engineers is to

1338
01:43:36,500 --> 01:43:38,166
have these, you know, the

1339
01:43:38,166 --> 01:43:39,958
right tools, right, the right

1340
01:43:39,958 --> 01:43:42,375
foundations, instead of having to fight,

1341
01:43:42,375 --> 01:43:44,416
you know, all these like small things

1342
01:43:44,416 --> 01:43:46,000
that degrade over time,

1343
01:43:46,083 --> 01:43:48,958
and then need to revisit them. And you

1344
01:43:48,958 --> 01:43:51,000
realize how silly you were

1345
01:43:51,000 --> 01:43:52,125
writing this code, you know,

1346
01:43:52,166 --> 01:43:54,708
last year kind of thing, it feels like

1347
01:43:54,708 --> 01:43:57,833
more harmonious and stable

1348
01:43:57,833 --> 01:43:59,708
Right. I love that. And

1349
01:43:59,708 --> 01:44:02,208
I think that is also something that has

1350
01:44:02,208 --> 01:44:04,041
really brought me to Effect.

1351
01:44:04,041 --> 01:44:06,625
And to flip it on its head,

1352
01:44:06,750 --> 01:44:10,250
something that I experienced so many

1353
01:44:10,250 --> 01:44:13,083
times and have observed so many other

1354
01:44:13,083 --> 01:44:15,083
teams as sort of like a

1355
01:44:15,541 --> 01:44:18,333
malfunction of engineering teams and of

1356
01:44:18,333 --> 01:44:20,541
projects that engineers are

1357
01:44:20,541 --> 01:44:22,916
afraid to make changes in a

1358
01:44:22,916 --> 01:44:25,791
project. And I've seen this time and time

1359
01:44:25,791 --> 01:44:27,333
and time again. And when

1360
01:44:27,333 --> 01:44:29,041
you're afraid to make changes to a

1361
01:44:29,041 --> 01:44:31,666
project, particularly if the code was

1362
01:44:31,666 --> 01:44:32,916
written by someone else, maybe

1363
01:44:32,916 --> 01:44:34,500
the person is no longer there.

1364
01:44:35,083 --> 01:44:36,958
That's terrible. Like if you're, if

1365
01:44:36,958 --> 01:44:38,250
you're afraid to change something, you

1366
01:44:38,250 --> 01:44:39,333
might not change it and

1367
01:44:39,333 --> 01:44:41,458
you might not improve it. Or if you

1368
01:44:41,458 --> 01:44:42,375
change it, you don't know

1369
01:44:42,375 --> 01:44:44,375
about the consequences, etc.

1370
01:44:45,208 --> 01:44:48,416
And effect allows you to, gives you the

1371
01:44:48,416 --> 01:44:51,250
confidence to change something and you

1372
01:44:51,250 --> 01:44:52,041
know what's going to

1373
01:44:52,041 --> 01:44:54,625
happen. It even makes it fun to do so.

1374
01:44:54,625 --> 01:44:55,375
And I think that's

1375
01:44:55,375 --> 01:44:58,750
sort of like a twin to the

1376
01:45:00,333 --> 01:45:03,416
aspect of composability, almost like the

1377
01:45:03,416 --> 01:45:04,791
other side of the same

1378
01:45:04,791 --> 01:45:07,958
coin, where if you can compose

1379
01:45:07,958 --> 01:45:10,125
things together, you can decompose things

1380
01:45:10,125 --> 01:45:11,833
that makes, that's, those

1381
01:45:11,833 --> 01:45:13,750
are just aspects of changing

1382
01:45:13,916 --> 01:45:17,166
something and changing not in a big bang

1383
01:45:17,166 --> 01:45:19,708
way, but just moving things

1384
01:45:19,708 --> 01:45:21,416
around almost feels like a,

1385
01:45:21,416 --> 01:45:23,458
like a dance. We're getting a little bit

1386
01:45:23,458 --> 01:45:26,458
too, too like pie in the sky

1387
01:45:26,458 --> 01:45:27,666
here, but that's really like

1388
01:45:27,666 --> 01:45:29,791
my reality as well, like working with

1389
01:45:29,791 --> 01:45:31,083
Effect and one of the things

1390
01:45:31,083 --> 01:45:33,000
that I like so much about it.

1391
01:45:33,625 --> 01:45:35,708
And another thing here may be looking a

1392
01:45:35,708 --> 01:45:36,625
little bit more into the

1393
01:45:36,625 --> 01:45:37,666
future, but we're increasingly

1394
01:45:37,875 --> 01:45:40,875
living in the future where we get, where

1395
01:45:40,875 --> 01:45:42,541
we do a lot of our code

1396
01:45:42,541 --> 01:45:44,625
development in an AI-assisted way.

1397
01:45:45,375 --> 01:45:48,166
Now it's maybe no longer just us, us as

1398
01:45:48,166 --> 01:45:50,250
engineers doing performing

1399
01:45:50,250 --> 01:45:52,625
changes on our code, but it's now

1400
01:45:52,625 --> 01:45:54,750
AI systems performing changes on our

1401
01:45:54,750 --> 01:45:56,541
code. And this is where the same

1402
01:45:56,541 --> 01:45:58,791
underlying dynamic is even more

1403
01:45:58,833 --> 01:46:02,958
severe. If there is a system, if there is

1404
01:46:02,958 --> 01:46:04,916
some actor here who's

1405
01:46:04,916 --> 01:46:07,333
changing our code, who is maybe

1406
01:46:07,375 --> 01:46:10,083
even less competent or less knowledgeable

1407
01:46:10,083 --> 01:46:12,333
about this, then maybe even

1408
01:46:12,333 --> 01:46:14,375
more scary to make changes

1409
01:46:14,375 --> 01:46:18,000
to a system. And if the material here,

1410
01:46:18,000 --> 01:46:18,833
the house that we're

1411
01:46:18,833 --> 01:46:19,750
building that you've mentioned,

1412
01:46:20,500 --> 01:46:24,708
is where it's inviting to have changes be

1413
01:46:24,708 --> 01:46:27,708
made, that sets an even better foundation

1414
01:46:27,708 --> 01:46:29,833
for those AI-assisted,

1415
01:46:30,625 --> 01:46:33,208
for this AI-assisted future. So that's

1416
01:46:33,208 --> 01:46:34,833
something I love thinking about.

1417
01:46:35,625 --> 01:46:41,041
Yeah, I agree. I think the guardrails

1418
01:46:41,041 --> 01:46:42,416
here are so important,

1419
01:46:42,416 --> 01:46:43,791
right? You want to make sure that,

1420
01:46:44,791 --> 01:46:49,541
whatever the LLM generates has as little

1421
01:46:49,541 --> 01:46:51,875
unintended side effects as possible,

1422
01:46:52,333 --> 01:46:55,083
because it could hallucinate some code.

1423
01:46:55,416 --> 01:46:57,541
So if you can make sure that

1424
01:46:57,541 --> 01:46:59,958
the blast radius is as tight,

1425
01:46:59,958 --> 01:47:01,875
small as possible, then I think you have

1426
01:47:01,875 --> 01:47:03,541
a really good foundation. Obviously, I

1427
01:47:03,541 --> 01:47:04,125
don't know where this

1428
01:47:04,125 --> 01:47:05,583
is heading. Maybe we're going to be

1429
01:47:05,583 --> 01:47:07,375
completely wrong and that we're not even

1430
01:47:07,375 --> 01:47:07,916
going to be thinking

1431
01:47:07,916 --> 01:47:12,166
about code in the same way in the future.

1432
01:47:12,166 --> 01:47:13,208
But it feels like it's a

1433
01:47:13,208 --> 01:47:16,583
really good way of ensuring

1434
01:47:16,708 --> 01:47:20,000
that whatever an LLM generates stays

1435
01:47:20,000 --> 01:47:24,000
within the intended radius.

1436
01:47:25,916 --> 01:47:28,208
Exactly. And I think just to round this

1437
01:47:28,208 --> 01:47:30,750
part out, Effect gives

1438
01:47:30,750 --> 01:47:33,958
you a middle ground between

1439
01:47:34,416 --> 01:47:37,916
a natural language like English that

1440
01:47:37,916 --> 01:47:40,125
might be more intuitive to

1441
01:47:40,125 --> 01:47:41,958
describe what a system should do,

1442
01:47:41,958 --> 01:47:45,791
but maybe less concise, as opposed to a

1443
01:47:45,791 --> 01:47:47,208
type system or code,

1444
01:47:47,666 --> 01:47:49,083
which can be more concise,

1445
01:47:49,166 --> 01:47:51,208
but maybe less intuitive. And I feel

1446
01:47:51,208 --> 01:47:52,625
Effect is the best of

1447
01:47:52,625 --> 01:47:54,583
both worlds, where you can,

1448
01:47:54,583 --> 01:47:56,791
through the help of a type system, and

1449
01:47:56,791 --> 01:47:57,666
here in this case,

1450
01:47:58,083 --> 01:48:00,083
TypeScript provides a marvelous type

1451
01:48:00,166 --> 01:48:02,750
system that allows you to give you the

1452
01:48:02,750 --> 01:48:04,541
correctness benefits that you wouldn't

1453
01:48:04,541 --> 01:48:06,416
get from English, yet

1454
01:48:06,916 --> 01:48:09,791
it gives you that more intuitive way to

1455
01:48:09,791 --> 01:48:13,125
express and compose things. I feel like

1456
01:48:13,125 --> 01:48:14,458
Effect is converging

1457
01:48:14,458 --> 01:48:16,333
towards something that's the best of both

1458
01:48:16,333 --> 01:48:18,250
worlds here, that is

1459
01:48:18,250 --> 01:48:19,833
actually a wonderful substrate

1460
01:48:20,250 --> 01:48:22,791
for AIs to also compose

1461
01:48:22,791 --> 01:48:24,125
systems out of.

1462
01:48:24,125 --> 01:48:26,083
Wish that the latest versions of LLMs

1463
01:48:26,083 --> 01:48:27,416
have even better

1464
01:48:27,416 --> 01:48:28,958
understanding of the latest developments

1465
01:48:28,958 --> 01:48:31,333
in Effect. But I think you mentioned that

1466
01:48:31,333 --> 01:48:32,875
you have a nice hack, which is to

1467
01:48:33,500 --> 01:48:36,625
clone the Effect repository in cursor and

1468
01:48:36,625 --> 01:48:38,375
then have it look at

1469
01:48:38,375 --> 01:48:39,416
that while you're coding.

1470
01:48:40,291 --> 01:48:42,750
Yeah, so that's actually a shout out to

1471
01:48:42,750 --> 01:48:44,416
our friend Tim

1472
01:48:44,416 --> 01:48:47,500
Suchanek. He taught me about

1473
01:48:48,250 --> 01:48:50,333
this little trick, and I've since applied

1474
01:48:50,333 --> 01:48:52,250
it many times also for other projects.

1475
01:48:52,750 --> 01:48:54,875
I think we're currently in this uncanny

1476
01:48:54,875 --> 01:48:57,666
valley, where LLMs always

1477
01:48:57,666 --> 01:48:59,875
lag behind on the latest and

1478
01:48:59,875 --> 01:49:02,833
greatest of actual information. The

1479
01:49:02,833 --> 01:49:04,541
Effect docs, for example, in

1480
01:49:04,541 --> 01:49:06,458
particular, they have really

1481
01:49:06,833 --> 01:49:09,291
advanced a lot, got a lot better over the

1482
01:49:09,291 --> 01:49:10,958
last couple of months. And

1483
01:49:10,958 --> 01:49:13,000
those LLMs that we're using

1484
01:49:13,000 --> 01:49:15,833
on a daily basis have not fully caught up

1485
01:49:15,833 --> 01:49:17,833
to that level yet, and

1486
01:49:17,833 --> 01:49:19,208
are also sometimes trained

1487
01:49:19,208 --> 01:49:21,791
on old code snippets, different syntax,

1488
01:49:22,041 --> 01:49:24,083
etc. And so when you ask

1489
01:49:24,083 --> 01:49:25,875
them, you might get an outdated

1490
01:49:25,875 --> 01:49:29,500
response. So what Tim is doing, and since

1491
01:49:29,500 --> 01:49:31,208
he's taught me about

1492
01:49:31,208 --> 01:49:32,375
this as well, is basically

1493
01:49:33,125 --> 01:49:36,500
check out the Effect code base on your

1494
01:49:36,500 --> 01:49:38,166
computer locally, open

1495
01:49:38,166 --> 01:49:39,541
Cursor in it, and then

1496
01:49:40,041 --> 01:49:43,291
Cursor uses the full Effect repo with

1497
01:49:43,291 --> 01:49:44,541
all the examples, tests,

1498
01:49:44,833 --> 01:49:46,833
etc. as the context. And then

1499
01:49:46,875 --> 01:49:49,625
inside of that, you use the Cursor chat

1500
01:49:49,625 --> 01:49:51,250
to ask your question, and

1501
01:49:51,250 --> 01:49:52,625
you're going to get a really

1502
01:49:52,625 --> 01:49:55,458
useful result. So I've been using this a

1503
01:49:55,458 --> 01:49:57,208
bunch myself, but we're

1504
01:49:57,208 --> 01:49:58,916
also working on some exciting

1505
01:49:59,166 --> 01:50:02,750
improvements to the Effect docs, etc.,

1506
01:50:02,750 --> 01:50:04,791
where we're trying to

1507
01:50:04,791 --> 01:50:07,166
combine the latest and greatest

1508
01:50:07,375 --> 01:50:11,500
documentation with some of our own AI

1509
01:50:11,500 --> 01:50:13,750
developments as well. So stay tuned for

1510
01:50:13,750 --> 01:50:14,958
that. You won't need

1511
01:50:14,958 --> 01:50:17,791
those little tricks for too much longer.

1512
01:50:18,291 --> 01:50:19,041
So Michael,

1513
01:50:19,333 --> 01:50:21,041
thank you so much for taking

1514
01:50:21,125 --> 01:50:24,291
out so much of your busy day to share

1515
01:50:24,291 --> 01:50:26,500
about your experience and journey with

1516
01:50:26,500 --> 01:50:28,625
Effect. Really greatly

1517
01:50:28,833 --> 01:50:31,250
appreciate that you share all of that

1518
01:50:31,250 --> 01:50:32,666
with the entire audience

1519
01:50:32,666 --> 01:50:35,583
here. Before rounding this out,

1520
01:50:35,583 --> 01:50:37,500
is there anything else you would like to

1521
01:50:37,500 --> 01:50:38,958
share with the folks

1522
01:50:38,958 --> 01:50:42,666
listening? I'm sure that you're

1523
01:50:42,666 --> 01:50:44,875
very busy building a lot of things, but

1524
01:50:44,875 --> 01:50:46,958
you're also interested in

1525
01:50:46,958 --> 01:50:48,583
bringing on more engineers.

1526
01:50:49,541 --> 01:50:51,041
Anyone in particular who

1527
01:50:51,041 --> 01:50:52,541
should reach out to you?

1528
01:50:53,250 --> 01:50:57,208
Yeah, so we are constantly hiring and we

1529
01:50:57,208 --> 01:51:00,666
are obviously, it's a full TypeScript

1530
01:51:01,000 --> 01:51:04,875
Effect code base, but we are also very

1531
01:51:04,875 --> 01:51:05,708
much looking for

1532
01:51:05,708 --> 01:51:07,458
engineers with an ML background.

1533
01:51:07,916 --> 01:51:11,541
And we would warmly welcome them even if

1534
01:51:11,541 --> 01:51:12,250
they don't have

1535
01:51:12,250 --> 01:51:14,833
specific TypeScript experience.

1536
01:51:14,875 --> 01:51:18,333
So yeah, if you're interested in working

1537
01:51:18,333 --> 01:51:20,666
on such a code base, which I

1538
01:51:20,666 --> 01:51:21,833
think is really, really nice

1539
01:51:22,250 --> 01:51:24,708
and working on some really interesting

1540
01:51:24,708 --> 01:51:26,458
LLM related topics,

1541
01:51:27,208 --> 01:51:29,666
then absolutely reach out.

1542
01:51:30,791 --> 01:51:33,416
Yeah, I couldn't give you a warmer

1543
01:51:33,416 --> 01:51:35,333
recommendation to work at

1544
01:51:35,333 --> 01:51:37,958
Markprompt. Michael, Marie,

1545
01:51:38,583 --> 01:51:40,333
Elliot, all the folks working at

1546
01:51:40,333 --> 01:51:43,791
Markprompt are A plus humans. If I

1547
01:51:43,791 --> 01:51:45,500
wouldn't be doing all of the

1548
01:51:45,500 --> 01:51:47,583
things I'm doing, I'd strongly consider

1549
01:51:47,583 --> 01:51:49,166
working with you all as

1550
01:51:49,166 --> 01:51:50,875
well. So whoever gets a chance

1551
01:51:50,875 --> 01:51:53,291
to work with you, I think you're making a

1552
01:51:53,291 --> 01:51:55,375
very smart decision. So

1553
01:51:55,375 --> 01:51:57,916
now moving back my focus to

1554
01:51:57,916 --> 01:52:00,916
you, Michael, thank you so much again for

1555
01:52:00,916 --> 01:52:03,083
taking time, sharing all of your

1556
01:52:03,083 --> 01:52:04,666
experience and all of

1557
01:52:05,041 --> 01:52:06,958
those anecdotes with us. I greatly

1558
01:52:06,958 --> 01:52:08,708
appreciate it. Well, thank

1559
01:52:08,708 --> 01:52:09,750
you, Johannes. Always a pleasure

1560
01:52:09,791 --> 01:52:11,791
to speak with you. Awesome.

1561
01:52:12,250 --> 01:52:13,833
Thank you so much. Thank you.