{
  "video_id": "Wmp2Tku2PrI",
  "channel_slug": "aidotengineer",
  "channel_handle": "aidotengineer",
  "title": "How I code Effect Apps — Michael Arnaldi, Creator, Effect",
  "duration_seconds": 6184.0,
  "url": "https://www.youtube.com/watch?v=Wmp2Tku2PrI",
  "upload_date": "",
  "transcript": "So, welcome everybody. Um, just setting\nup the context for this workshop.\nI had a lot of ideas to potentially\nprepare but at the end I thought we are\nvibe engineering for this to be\nauthentic it has to be from scratch so I\nactually prepared absolutely nothing\nthat means we can take any path that we\nwant\nand let's hope this is real enough first\nof all I'd like to know from the crowd\ndo you already effect\nyou know zero like what's your level of\nfamiliarity with AI tooling and some\nkind of questions like that lucky enough\nwe're not too many so I hope this can be\nas interactive as possible maybe let's\njust start I know Chris\nhello hi\nfamiliarity with AI and with effect\nsun Okay, good.\nRunning V4 in production.\nRunning V4 in production. Against\nadvice, by the way.\nGood.\nmy hand of this year doing everything\nand the reason I'm particularly\ninterested with the effect is like it's\nencouraging so much safety\nso my agents cannot become small\nand the reason uh I want effect was we\nhad one API client\nI trans\nand now I'm more interested how you make\nthe effect more discovered by the agents\nokay\nI saw the idea about having the loy\nnot convinced with that so I'm curious\nGood.\nGood. Well, how about you?\nYeah,\nbut heard much about the effect.\nSounds good. Sounds good.\nGood. So pretty aogeneous crowd all\ninterested in some sort of how to use\nagents effectively with effect pun\nintended.\nYou pointed out at a at a very good\nthing which is cloning uh giving the\nrepository access to giving the agent\naccess to to the repository. And in\nreality, this session should just be\ncalled just clone the [ __ ] repo\nand get and be done with it. And really\nlike I' I've also have not been coding\nby hand since about late this summer. So\nit's been quite a while. I started\nprogramming when I was 12 years old. So\nit's quite an odd feeling to get to the\npoint where you know you're no longer\nwriting code by hand. And most of what I\ndo is library level coding. So it's\npretty low level usually fairly complex\ntype machinery stuff that\nused to require\na very good understanding of the\nlanguage of how the user interacts with\nyour software and so on and so forth.\nnot diminishing in any way up level\ndevelopment just that the way you treat\na language if you have to build a\nlibrary versus the way you treat the\nlanguage if you are building an app on\ntop of it is usually very different. Now\nsometimes in app land you have the same\nrequirements as library land especially\nwhen you need to you know generalize\nabstract over some patterns make them uh\nrepeatable well um remove the verbosity\nfrom the repetitions and so on and so\nforth. So there's some crossing there,\nbut I definitely thought that uh AI\nwould be more useful in upland. And I\ndidn't see much usage at library level\nland. And I was dead wrong because I'm\nnot writing code by hand. I have not\nwrote any line of code by hand for a\nwhile. And I've done that in Typescript.\nI've done that in Rust.\nAnd the funny element is given I mostly\nwrite libraries,\nI usually interact with code bases that\nhave zero documentation,\nthat have zero best practices available\nonline.\nAnd so I couldn't really use the usual\nlet's just add an MCP server to get\naccess to the documentation or hoping\nthat the models have been trained on the\ndocumentation enough to be directly\nuseful.\nAnd the reality is with LLMs like people\ntreat them like a human brain but they\nare very different.\nWe learn continuously.\nThis is a learning experience. Once we\nget out of this room, hopefully you're\ngoing to know a little bit more\nfrom the starting point on when you come\nin and your brain will keep going and\nwill internalize more and more patterns\nover time.\nThen you go to sleep. Your brain cleans\nup a little bit of the mess of\nirrelevant information that you got\nduring the day. And there's this whole\nprocess of transforming\nexperience. So the the word that we\nexperience every day into long-term\nmemory\nwith LLMs. This does not happen with\nLLMs. get a pre-training phase where LM\nare trained on all the world of\nexistence of existing knowledge. Usually\nthey get trained on the whole internet.\nThen they get specialized in some tasks\nand then there's the whole post-raining\nphase where models are fine-tuned to act\non specific things. For example, coding\nagents are generic models that have been\nreinforced that they have had passes of\nreinforcement learning to operate on\ncode bases. The whole post-raining phase\nof a of a large language model dedicated\nto coding is letting the model rip\nthrough code bases and having\nevaluations that tells the training\nphase how is the model performing. Is it\ndoing good? Is it doing bad? Does the\ncode compile after this change? Does the\ncode fail to compile after this change?\nAnd so on and so forth. But once that is\ndone, it's done. There's no more\nknowledge that comes into the model\nevery day. So\nif you interact with a model today and\nyou tell you tell something to the model\nand you say, \"Hey, I want you to do this\nin a very specific way. Tomorrow it's\nnot going to remember.\"\nSo how do you make it remember that is\nthe that is the big question\nand\nmodels\nyou have to think of them like\nyou're chatting with them but the\nreality is you are basically appending\nmessages onto a fixed size array which\nis called the context window and\ncontext window is limited. Now there are\nmodels with a 1 million tokens context\nwindow and that's not necessarily a good\nidea because\nthe context window of the model is what\nis pushed to the neural network and the\nneural network is going to try to\npredict what's coming next. So if you\npush more information, there's a very\ngood chance you're going to confuse the\nmodel, which is why a 1 million context\nwindow is not necessarily helpful,\nespecially if you're doing multiple\nthings in the same context.\nThat really means\nwe have to architect around\na dump process. We have to architect\naround some machine that had knowledge\nof six months ago at best that it's not\ngoing to remember everything because\neven if you have\none trillion parameters in the model or\neven if you have 10 trillion parameters\nin the model that's not enough to store\nall the human knowledge. So you're\nalways going to get compressed knowledge\nand in the best case scenario you have\nsome ability of generalization in the\nmodel so that the model can say hey I\nknow AB\nmaybe I can do C because it's similar to\nA and B and you have some form\nof this emergent behavior and and\ncapability of reasoning on new problems\nbut models have become very good I've\nsaid it by myself I'm not writing code\nby hand since at a minimum six or eight\nmonths\nSo that means even if the machine is\ndumb, it's already at the point where we\ncan leverage it to do good. But how do\nwe do it? Now\nif the assumption is the model has\noutdated knowledge, we need a way for\nthe model to get new knowledge.\nAnd we said that those models that we\nuse for coding have been reinforc have\nwent through reinforcement learning to\nbe able to understand your own codebase,\nmake changes in your own codebase\nand replicate patterns that exist in\nyour own codebase.\nThey haven't really been trained on\nreading human documentation.\nThey haven't been trained on using an\nMCP server that they never seen. They've\nbeen trained primarily to consume and\nproduce code.\nSo eight months ago I was thinking what\nif\nI just give the model access to code\nthat means if I want to use effect\nI'm going to add the effect repository\nin my directory.\njust masquerading the effect code base\nas my own codebase and maybe I can trick\nthe model into thinking that it's just\none big code base and that it would\nexplore it and would progressively use\nit to build up the the required\nknowledge and to sort of clone the\npatterns\nand there's various ways of doing that.\nOne could argue the model already has\naccess to library code by having it in\nnpm in node modules\nbut coding agents have been trained to\nfocus on your own code not on the code\nthat is on node modules. So if you have\nit in node modules, the model is the\noptimized.\nIt's not going to look at it with the\nsame frequency as it look at your own\ncode.\nIf you have it in a gignor\ndirectory, the models have been trained\nnot to look at files that are gignored.\nFor example, cursor does not index stuff\nthat is git ignored.\nSo there are all of those sort of random\nrestrictions that we figure out while\nwhile developing.\nAnd the only way I found the models to\nbe good regardless of the language,\nregardless of what you use, is if you\njust clone the [ __ ] repo, which is\nthe point of this work. So this is a\ncompletely empty project. I have some\nideas of where we could take this. My\nidea would be to set up um a bun\nrepository, use vest for testing, uh use\nbuild up some kind of HTTP server,\nideally providing an open API\ndocumentation\nfor consumption, build kind of type-\nsafe client to interact with the back\nend. uh hopefully if we have enough time\nI'm not sure um tap into the word of\nworkflows and and clustering for\npersistent operations in the in the back\nend and really I have nothing set it up.\nSo how do I usually start? Well, I would\nlike you to\nI start nice with the model but as soon\nas it derails\nyou're going to see I'm going to start\nto insult the model. It's fun because it\ncannot really answer you back. If you\ndon't like the answer, you can just shut\nit down. It's not like a human that gets\noffended.\nMaybe I would like to set up a project\nusing\nthe project should also include\nsetup of Vest\nand\ntype script\ncheck\nscript\nI'm using GPT 5.4\nwhen I started this journey I was using\nset 4 there many difference between set\n4 and GPT 5.4 four, namely set four felt\nlike a kid with a knife running through\nthe house. That's that's an example that\ncomes from Joffrey Huntley, the the\nauthor of the Ralph Loops. But even as a\nkid running through the house with a\nknife, it was still enough to do coding.\nand GP. Now we have models like Opus\n4.5,\nGPT 5.4\nthat are much much better.\nBut a very interesting\nelement to to think about is\nopen weights models are\nkind of lagging behind by three to six\nmonths compared to frontier models.\nWhich means now we already have models\nin the open that are smarter\ncompared to set 4 which I already used\nin library level development.\nHow long would it take for those open\nweight models to become good enough to\nbe used in our daily operations? I don't\nknow.\nIt's just one thought that lately I have\nmore and more especially because\nwell anthropic is putting arbitrary\nrestrictions on how we use their models.\nSo I don't really want to use entropic\nmodels. Open AAI is good for now. Who\nknows what are what they're going to do\nin a in a year or two.\nAnd I like open source of course.\nOkay. I don't have a g repo created.\nCreate an empty\ng repo. And by the way, if you have\nquestions, if you want to interrupt me,\nthis is supposed to be interactive. I'm\nI'm here to entertain you for another\nhour and a half.\nInitialize the repo. Okay, this is done.\nIt's amazing that using GPT 5.4 for with\nopen code would create by default a code\nMD\nI think like this is this is from from\nbun yeah let's trash this\nabsolutely has nothing to do with this\nperfect marketing strategy\nplus they they've said it wasn't a real\nfool and two days after they announced\nMAS as the new model.\nOkay. I create a source\nand test directory.\nLet's see what created.\nOkay. Types bun\nbundler mode. No emit.\nThat's fine.\nstrict\nskip lip check. That's fine. Implicit\noverride.\nThat's good.\nYes.\nAlso\nactually move the\nfiles\nin the proper\ndirectory.\nmoving the entry file. Good. Seems smart\nenough.\nRuns a basic smoke test. Okay.\nOkay. So, that's a good starting point.\nWe verified with bun run test, bun run\ntype check. Good. Uh we want to add\neffect\nbeta.\nWe're going to use effect v4. It's not\nyet released for production usage except\nhe uses in production already. So if I\nhave any problem, I'm going to ask you.\nIt's fine.\nYes, it's effect small.\nSmall because it used to be small and\nevolve to become bigger.\nStill very uh very thin in bundle size.\nOkay, 1% 14k.\nIt's plenty of context left.\nUh want to add effect beta\nand we want to use\neffect\ntest to write the tests.\nI will. I will. That's next. That's\nnext.\nAnd speaking of that,\nI want to try to use the TSGO version of\nit.\nNow, I never used this. So\nwhat is I haven't used it so I don't\nknow how to use it\nlet's set up\nas the compiler\nas the\ntype\nCheck\nthe read me\nand set it up. Not sure if this is going\nto work or not.\nOh, the the actual base compiler.\nYes. I I don't know if Matia\nallowed.\nYeah, it does. The point is it does not\nuse it and\nwe could just do an alias install. So\ninstall typescript as something else but\nI'm not sure if\nhe did it.\nMaybe let's follow the normal the normal\npractice. Let's install TypeScript\nGo instead of\nTypescript. Would it be able to do this?\nWho knows?\nWe will find out.\nIs this the package? No, I don't think\nthis is the package.\nI think they just stole my crypto\nwallet. Except I do not have one. So\ncheck from here.\nOh,\nthe npm the npm package name TypeScript\nGo is only a placeholder security\npackage.\nSo I use the real preview compiler that\nprovides the TSGO binary. Well, that\nthat was probably a good idea.\nUh script ts go no emit.\nLet's see\nbun\nexact\ngo. Okay.\nOkay. Type check.\nType check.\nOkay. Set up VS code to use\nDSGO\nVS\ngo\nLSP\nwe work maybe.\nYes, that that I need.\nThere we go. Native preview. That's it.\nOkay, I did install that.\nI need to reload the window most likely.\nLet's go.\nOkay, maybe it worked.\nThen let's go here.\nAnd\nyeah, I should be able to do that.\nBut also there is a nice\nwill not be loaded if files are\nspecified.\nCommand line\nconfig to skip this error. What\nI'm going to feed it to the agent in a\nminute.\nIt's bun that gives issues\nprobably. Maybe not.\nYes, it is bun.\nThen let me stop this.\nuh select the TS config to configure\nthis one. This other is a package JSON\ninstalling dev dependencies.\nSelect all.\nWhat is this?\nThat's BS code. That's fine.\nThis needs a lot of work.\nDo we have the effect pattern installed?\nOh gosh.\nWhere is this coming from? Who knows?\nOkay. Okay. Okay.\nOne.\nInstall. Okay. That's installed.\nLet's see if it catches anything.\nImport.\nfrom effect\n100.\nNope, that's a dangling effect. That\nshould be\nI think I've done it.\nYou mean the prepare one?\nYeah, I did. Um,\nmaybe I need to reload.\nReload after that.\nYes, was easy. The Windows solution just\nrestarted.\nOkay, so we have it. Uh and now\nnow we want to\nwe have some diagnostic severity to\nsuggestion warning and so on and so\nforth.\nFor AI we would like to turn everything\ninto an error so that the\nThe LLM cannot\ncannot pass cannot accept code that has\nany remote resemblance or an error. So\nthis is\na project where we will use AI a lot. We\nwant all diagnostics\navailable\nfor\nto be set to error.\nI should switch from\nWhat is the model doing?\nDid it update the TS config? It did not.\nOh, I'm updating the TS config. Okay.\nNo, no,\nno. Uh, and that that's another\ninteresting point. Uh, the effect\nsolutions. Uh, there is a website called\neffect.solutions.\nIt's a really nice website. Uh Kit\nLangton did this\nand it's kind of a quick start to use\neffect in an in an AI project and it\ndoes install the language service and\nstrict policy defaults and so on and so\nforth. But then it uses uh a CLI to give\nthe model access to the effect repo\nand\nthe model needs to know how to use the\nCLI. So it's kind of a dog beating its\ntail.\nYes.\nYes, but\nthere are some markdown files,\nbut it it doesn't work as well. And if\nyou actually read at some point, it says\nyou should actually just clone the\nrepository.\nOkay, this this looks exactly what I had\nin mind. So, we have all the diagnostics\nset to error.\nwhich is good. It's exactly what we\nwant.\nLoad window. Okay.\nI also want to\nformat\non save to true\njust because it's annoying otherwise.\nOkay. Very good point. Uh commit\ncurrent\ncommit current.\nNow I want to add effects more as a sub\ntree.\nOkay, it's committed. Good.\nNow create a dot repos folder and add as\na g sub tree without history\nsquashed\nuh in repos\neffect.\nWho knows if it's going to be able to do\nit.\nAt least it did.\nOkay, here.\nWhy is it trying to\nOkay.\nOkay, we have it.\nLet's just check git log. Yep, it did\naudit.\nOkay. And now we are at the point where\nwe can start to do our research. For\nexample, we said we want to create an\nHTTP API.\nI would\nclean up this. Open a new session to\navoid context pollution.\nYou have access\nto the effect repository\nat repos. Actually, let's do something\nelse before we want\nto set up an agents.mmd.\nsetup and agents.m MD listing the\ncommands\navailable\nlike one run type check\nand specify\nthat you have access to the effect\nrepository at repos effect and you\nshould use that to extract\nbest practices. this\nlook at how things works\netc.\nNow the agents.mmd now we're going to\nget an initial prototype as you work in\nthe project you're going to evolve that\nyou're going to add more commands to it\nyou're going to add rules when you spot\nthat some bet patterns are created in\ncode\none thing we have not set it up yet is a\nllinter\nuh llinter is going to be an essential\npiece of the back pressure loop that\nhelps the model drive in the right\ndirection.\nIf you want a kind of fully working\nsetup, uh I have a repository of mine\nthat I use for fun which is called\naccountability.\nuh in this repository\nyou can find\num a lot of things but for example I\nhave an ESLint config with a lot of\ncustom rules\nand those are like arbitrary for example\nI don't want the model to do an explicit\ntype assertion on things I want the\nmodel to use schema to check for the\nshape\nI have rules prohibiting the usage of X\nas Z. I have rules prohibiting the usage\nof any of unknown.\nBasically, I'm trying to avoid the model\nto do dumb stuff that I realized it was\ndoing in my code.\nNo.\nYeah. The same for unknown.\nAnd the funny thing is initially I\nbanned unknown because I wanted the\nmodel to not do as unknown as X. It\nfound that never is a bottom type. So\nyou can do as never as X. I like okay\nthen I I'm going to ban as and and now\nit's doing better.\nUh\nokay let's see what it created. Okay,\nthis is short.\nUse bun. Okay.\nAvailable project commands. That's fine.\nTest watch\nthis is going to create issues. I\nalready know because the model is going\nto try to run this and get stuck. Same\nwith dev servers.\nFact reference repositories. Good. Look\nat the for specific guidance.\nOkay, that's enough of a start mention\nin the agents.m MD that you should never\never\ntry to run commands\ncommands in watch mode. For example, you\nare not allowed to run\nor a dev server.\nOtherwise, it's going to try to run the\ndev server as the first thing and get\nstuck.\nOkay. What I like about OpenAI models is\nthat they are way more concise compared\nto entropic models. The same task with\nOpus would have probably wrote 200 lines\nof agents MD\nbut that's good. It's enough for it's\nenough as a start.\nSo we are back to square zero. We said\nwe want to create an HTTP API. I know\nnothing about effect.\nSo\nI would like to create an HTTP API that\nshould\nhave open API documentation\nand type save client\ngenerated\nby default.\nExplore the effect repo for patterns on\nhow\nto\ndo this.\nSave your research\ninto\npatterns\nhttp api.md.\nAsk me any question you need.\nAgain, I'm I'm starting from the\nperspective that\nI have no idea how to do this in effect.\nNo, I I find plan mode to be\nLike the issue with plan mode is that\nthe the model has crippled access to\ntools.\nSo it cannot easily do the same things\nthat it does outside of plan mode.\nSo not I don't make heavy usage of it. I\nusually do what's called specd driven\ndevelopment in the sense that the first\ntask I do with the model is I discuss\nwith the model how to create a spec for\nsomething then the spec is persisted as\na markdown file which is effectively my\nplan\nand I tell the model then to implement\nuh that usually the the second step I do\nin a ral loop because you've seen I\nalready restarted open code a few times\nto clean up the context window.\nDoing this manually is boring and you\nusually end up reusing the same context\nwindow for multiple things and it's\ngoing to just deoptimize the model at\nsome point because the context window is\nlimited. You're going to push a lot of\ninformation in and the earlier\ninformation is going to confuse the the\nmodel for the later information. So I\nuse a very simple bash script that\ntells the model pick up a small task\nimplement the small task and then exit\nand I run that in a loop.\nIt's funny how with with AI many times\nless is more.\nYou can have very complex architectures\naround context management and so on and\nso forth. At the end, the dumbest thing\never ends up working better.\nAnd we are doing research\nby ourselves and it looks like\nthere's actually very good margins of\nimprovement\nuh by reducing the number of tools that\nthe model has access to. For example, we\nhave been experimenting with a coding\nagent that has a single tool call which\nis called execute and it can execute\narbitrary TypeScript code including\ncalling Bosch through TypeScript.\nAnd in that scenario, the model doesn't\neven have access to a patch. It cannot\nchange files directly. It has to write a\nTypeScript file that changes the the\ncode and then it ends up doing\nTypeScript transformers asbased\ntransformations.\nIt's fantastic how you reduce the things\nthat the model can do and it it does\nbetter. So let's see save the research\nto HTTP API. Good. Main conclusion for\nthis repo the strongest default effect\npattern is to define the shared HTTP\nAPI.\nYou're absolutely right.\nDerive open API from it.\nMount the docs.\nOkay.\nOpen API generator only when you need\ngenerated client artifacted. We don't\nknow. We don't we don't need that. One\nquestion before I implement anything\nfurther. Do you want the primary pattern\nhere to be shared HTTP API with HTTP API\nclient make?\nNo,\nI am fine with a shared\nHTTP API.\nI don't need a committed\nclient in the repo itself.\nLet's see what it did here\nfor this workshop repo. The best part.\nOkay, this give you relevant upstream\nfiles.\nGood.\nIt look tests.\nNice.\nOkay, this looks like a decent\nenough. We should probably tell it what\nwe want\nto do.\nBut this is just generic patterns that\nwe're going to use as reference.\nSo list the files in\npatterns\nin the agents\nMD. So the agent has context\nof their\nexistence\nmodel does not care about grammar.\nAnd I feel like\nmany people uh raise the point that\na model is not good at something if it\nif it doesn't do good by default.\nI don't think there's anything more\nwrong with that statement. The model is\ngood when it can operate a large scale\ncodebase using patterns and it doesn't\nfail at scale. The zero to one problem\nis not really it's a problem for the\nfirst 10 days or 10 hours depending on\nwhat you're building.\nAnd\nas programmers\nif our job is not to write code\nour job should be to set up the\nrepositories in ways that the models can\nact good on it. So what I'm doing now is\nlike most of what I do when I operate a\ncoding agent at scale in a codebase even\nif the codebase has no concept of AI\nlike if I start in a project that is\nbrownfield codebase existing from five\nto 10 years no context set it up the\nfirst thing I do is let the model\nexplore the code clone the main\nlibraries that are used if you're using\na framework like tanstack or so on and\nso forth clone the code of tanstack\nrouter if you're using zvel clone the\ncode basel\nask the model to generate best practice\nfiles and so on and so forth once you\nhave all of it the model is going to be\nmuch more uh efficient\nso now that we have a little bit of\ncontext on http apis we can start\nimplementing one uh I do want to check\nsomething quickly because I'm using bun\nand I'm using vest\nuh there's a best run\ndoes vest run actually uses bun as the\nruntime or does it use note\nbecause if I recall there was a tag that\nI had to pass to V test to let it use\nbun and I don't want our test setup to\ndefer from our uh\nwhat is it doing? Uh no\nadd to V test that it should ignore\nanything in repos.\nIt was running the effect tests that it\nfound.\nYeah, there was no V test config\nwhatsoever. Good.\nadd to the test\nsomething that uses a bun API.\nI feel like I did it here. So I should\nhave\nthis one.\nOkay. Was I using note? probably\nyou should expect it to be defined\nbecause now we did one of the SQL\nmistakes. It had to make the test pass.\nIt changed the test to make it pass.\nWow.\nOkay.\nOkay, it did it.\nLet's now begin our HTTP API\nimplementation.\nSo we want to implement an HTTP\nAPI following\nthe patterns\nat\npattern st HTTP API. We want the\nAPI to\num expose\na todo\nfunctionality\nwhere you can\none create\ntodos\ndescription\ntitle\ndescription\nTwo, update todos,\nchange title,\netc.\nThree, flag todo as done or not.\nfor list todos.\nUh I should have done something else.\nDiscuss the plan with me and create a\nplans\nto API MD. So here I'm telling the LLM\nto\nread the pattern file that we created\nbefore where it's going to gather\ngeneric knowledge about the effect ways\nof doing things. It still has access to\nthe original code base of effect if it\nwants to. But now I'm creating a\nspecific plan\nto implement the API that I would like\nto uh that I would like to implement.\ndrafting the plan. Okay.\nTo shave. That's fine.\ninitial storage strategy.\nLet's do something different for\nstorage. Use effect SQL and um SQite\nstore.\nExplore the effect repo for how to do\nthat.\nand create patterns\npatterns\nSQL\nMD\nI realize we need a persistent strategy\nand I don't have a persistent strategy\nI know that effect has some SQL thing\nand again I'm\nusing the same process where I first\ngenerate some patterns for it.\nAnd this is also useful because\nyou may want to use something from\neffect but you may not want to use\neverything from effect. So if we were to\npush all the patterns in your repository\nby default, you would end up using\neverything from effect even if you don't\nwant to.\nThis is kind of self select. Uh so you\ncan pick and choose whatever\nyou want to use.\nEspecially in brownfield projects. This\nis very important because you don't want\nto refactor everything you already have.\nFor example, here I could have picked\ndiesel to do the persistence just as\nwell.\nMost likely we're going to develop some\nkind of CLI where\nyou can prefetch some patterns that are\nalready available\nand still let you pick and choose.\nAnd we also want to automate this kind\nof process of exploring something,\ncreate patterns out of it because the\npatterns that we have as best practices\nmight not exactly fit your needs. So you\nwould still maybe update them as a as a\nsecond step.\nthe model I use may not be as good as\nthe one that\nfor example like the PRs that are\nyou go and you read the code and some of\nthem are just\nlike\nand the code generates all genra\nlibrary authors are providing not like\nskills like software\nBut this kind of like pattern is like\neffect solutions but officially like\ndistributed by the package collocated.\nI feel like generally it's a good idea\nbut there are some caveats to that for\nexample even the agents.mmd standard\nis kind of not a standard because the\nway you prompt cloud and the way you\nprompt gpt is different. For example,\nyou've noticed I never wrote anything in\nuppercase.\nIf I were if I if I was using code, I\nwould write a lot of stuff in uppercase.\nThe reason is GPT gets scared if you\nscream at them at it. I don't even know\nhow to call the model. And uh if you\nscream at it, it's going to deoptimize\nand then be passive and like agree on\neverything.\nthat is not what you want. Uh with code,\nif you scream at it, it's going to pay\nattention to that specific sentence.\nSo that comes also in these shared\npatterns. I feel like the patterns\nshould be almost generated with the\nmodel you use versus being off the\nshelf. Now we can do that for like the\ntop three frontier models. All the GPT\nfamily is very similar. 5.3, 5.4, 4 5.2\nthere are there are not so many\ndifferences oppus set and haiku\nare also very similar so ideally we can\nhave the CLI where where it says which\nmodel do you use okay I'm going to\noptimize the context for this versus the\ncontext for that and it's annoying\nbecause you would obviously like to have\na standard\nI would love to maintain it\nyes Yes, it's very painful to to\nmaintain this stuff.\nOur\napproach is to make the code\nas good and self-explanatory with\nexamples and everything that any model\nyou use can generate those and then the\nCLI would generate them on the spot\nfor the model you use.\nThat's one approach. It may fail and in\nsix months we provide patterns for\neverything and just tell you please use\neither one or two.\nAnother very interesting argument is\nfine-tune an open source model to use\neffect patterns by default.\nWe thought of that\nkind of\nokay let's see\nupdate\nv htt no\nif you want the next step for me to\nupdate yes\ndo that this is the annoying part of GPT\nmodels\nThey are going to ask constantly for\ninput from you to continue.\nOPUS would have just done it.\nBut sometimes done wrong and you have to\nlike do it three times your session.\nThat's why I use GPT 5.4. Well, I'd like\nsome sort of fusion and you know an\ninbredad fusion of entropic models and\nopen AI models so that it doesn't ask me\nall the time because GPT usually\nespecially in complex tasks\ntakes its time but at the end the output\nis good.\nwith Opus is right. Sometimes it it\nlikes to take these shortcuts. And the\nfunny thing is if you let one sleep,\nit's gonna repeat like if you let one\nany sleep in your codebase and if you\nhave opus, it's going to do as any all\nthe time. It's like, oh, I can't do\nthis. Let me do that for everything. I\nneed this to compile. Let's remove the\ncode.\nYes. That's why in in this project and\nin accountability I was using ous and I\nhave a lint file of thousands of lines\nof code to prohibit any shortcut.\nI can start implementing this next. Yes,\nplease\nfeel like we've spent enough time\nand let's see what it does.\nSee, it's a it it's correctly looking up\nin the effect repo\nin the AI docs for uh ideas.\nThis most likely it's going to take a\nlittle bit\nwhich is positive.\nKind of\nIn some projects it was using schema by\ndefault and I didn't need a lot of uh\nback pressure for it.\nSometimes\nyes one example is the is the rule in\nIn accountability, I have\nthis yes lint rule\nSQL\ncustom yes lint rule to ban SQL type\nbecause it would write an SQL query. It\nwould write an interface and it would\njust this is the exam exact same thing\nas casting\nand I had to ban this pattern fully\nand using type parameters with SQL\ntemplate literally provides no runtime\nvalidation. use SQL schema. Find one.\nAnd you see that the the rule\nends up suggesting to use SQL schema.\nSo I'm more or less just watching what\nthe model produces and if there's\nsomething I don't like,\nI end up writing linked rules to\nprohibit that specific pattern.\nFor example, in in schema\nmany times it would for example have a\nuser ID as a string\nand then it would have another ID as a\nstring and you would of course have no\ntype safety whatsoever and the code\nwould try to pass one into the other. So\nI would force all identifiers to be\nbranded types and I would then prohibit\nthe usage of type casting because\notherwise it would do like this requires\na user ID let me do as user ID and it's\nlike yeah it's pointless you should\nvalidate the data so I would ban uh the\nusage of as and force them to use u\nconstructors. So instead of doing 100 as\nuser ID user ID domake\nor prohibit usage of constructors in\nplaces where you should do validation\nfor example\none case where that that I found was it\nwould do the the API layer as plain\nstrings\nand then use constructors inside the\nhandler to create the objects defeating\nthe purpose. then I would write rules\nfor the model to write validation\ndirectly in the schemas. So that I was\nbasically saying if you use a\nconstructor inside the handler most\nlikely you you're wrong. You should\nimprove the starting schema to provide\nthe validation at the edge. It's kind of\nbabysitting a junior developer\nwith a knife running through the kitchen\ninstead of a kid running through the\nkitchen with the knife.\nAnd this is still going.\nI\nboth models are exceptional.\nSometimes one model drives you nuts and\nyou try the other.\nThere's not much of a rule. Uh lately I\ntend to use more open AI models because\nI don't really like to be restricted on\nthe hardness that I can use.\nuh the\nCLI itself. I want to use open code. I\nwant to use my own\nTypeScript files that interact with the\nAI SDK natively and I'm prohibited from\ndoing that from anthropic.\nSo up until a few months ago when this\nwas allowed I would use mostly oppus\nwhen they enforced\ntheir policies against uh open code I\nswitch to open AI models and now I'm\nmost of the time just using open AI\nmodel models\nthere are some small edge cases for\nexample when you do UI oppus is much\nbetter than codex\nSo for\nthere are some specific things where one\nis clearly better than the other but for\nmost of the tasks they are they are the\nsame. I just had some experience for\nexample where\nGPT\nthought for half a day on a on a on a\nbug that I had and went nowhere and\noppus one shot at the solution but I had\nthe opposite experience too. So it's\nvery hard to know uh which one is which.\nOkay, let's see what what what is this\ncreating? Uh, okay. It created an SQL\nclient.\nThe layer looks\ncorrect.\nUh, has migrations.\nIt decided to\ninline\nthe migrations.\nOkay, that's a valid choice.\nOkay,\nit correctly provided\nthe SQL live layer to the migration\nlayers.\nThis feels like duplicated.\nThere is clear duplication between\nI used for this\ncreating\nit. It's also available\nsometimes refactor and it leaves one\ncode in place and it's like never\nexported in the same catches.\nOkay, good to know. Uh\nwe are in our experimentation. Another\nthing we're doing is we're using\nsemantic code search\nbecause we've noticed that a lot of\ntimes the model reimplements the same\nfeatures because it doesn't find it.\nAnd with semantic code search it finds\nit.\nWell, okay. Here's there's a duplication\nhere.\nprobably tell it that there is a\nduplication at some point.\nWant to check the API.\nExactly. You see it's using plain\nstrings for identifiers.\nSo one of the future things that we\nmight want to uh that we might want to\ndo is to tell it to use branded stuff.\nOkay. Okay. To do not found, it added a\nschema notation\nto flag that to do not found should be a\n404.\nThis looks decent.\nUh I don't understand why it sometimes\ncreates\nstrrus instead of classes. I personally\nprefer to use classes.\nSo I would in the future um\neither create a best practice to prefer\nclasses or depending on how strict I\nwant create a lint rule to prohibit\nusage of schema.struct in specific files\nand stuff like that.\nFor now it's obviously it's fine.\nDoesn't need to.\nNot sure. There might be, but it's not\nflagging anything here. So, and the LSP\nis on\nlint all the files\nlinked with what? We don't have a\nllinter in place.\nGood point. We also do not have um\nformatter in place.\nLet's ignore for now.\nLet's see.\nOkay.\nclient with a base URL.\nThat's good.\nWe have the live handler.\nServer\nindex is just exporting everything.\nThe index.ts\nshow probably\nrun the server instead of\nexporting\neverything.\nDo that\ncondition\nchecking that the file is main. So it\ndoesn't\nrun when you import the file.\nI also created some tests.\nWhat? What is doing here?\nIt created an arbitrary with HTTP\nto run an effect.\nMake test HTTP live.\nOkay, it's one way.\nDo the test actually pass? Come on. Run\ntest. I'd be surprised. Wow.\nUh, is there a start command?\nadd a start command to start the API\nserver and tell me where to find\nthe open API\ndocs.\nOkay, it really likes this pattern.\nAs a future thing, I would probably just\ntell it to use it layer instead of\nusing the width repository\nand with\nthing. But let's see if if at least it\nworks.\nOne run start.\nGood\nlisting to those.\nLet's check the open API. Good. There is\nan open API.\ncreated.\nThis looks decent as a first.\nChoose the schemas properly.\nGood.\nOkay. Then let's let me\nIt did create a database here.\nLet me maybe get ignore\nthe full DB\nto DB all\nto DB\nto do. You're right.\nYeah,\nno longer able to write anything by\nhand.\nYes.\nOkay, let's actually clean up the tests\na little bit.\nSo\nclean.\nYou see, I'm fooling myself in wanting\nto use the same session over and over\nagain.\nThat's when Ralph loops are really\nuseful.\nWe created a lot of mess.\nYou created a lot of mess in tests.\nClean up everything. This should be the\ncleanest\ncode you've ever\nseen. Not like the crappy Python code\nyou've been trained on.\nDo not use patterns like\nsimply use it layer with layer\nand put utilities in\ntheir own folder. No offense to Python\ndevelopers, of course.\nProbably. Now, now I'm winging it. I'm\ngoing to see if it's able to do it. Uh\nif it does, once it's done, I'm going to\ncreate a pattern from it. But yes, that\nwould have been a good idea.\nWhich is why automating the process is\nvery important because we are lazy. Like\nnow I was so lazy that I didn't want to\ncreate\na pattern for it.\nMaybe I'll use test layers. Maybe.\nMaybe.\nOh, the bed pattern.\nIt basically created a function to\nprovide a layer\nto an effect. It built the layer\nmanually.\nIt wrapped everything in effect. sccoped\nwhich is going to close the layer once\nthis is done.\nAnd my guess is that it did this because\nthis pattern is actually used to test\nsome layered internals in the codebase.\nBut it's completely unnecessary here.\nBut if you look at the file, even\nwithout knowing\ndetails of effect,\nit stinks.\nSomething's not right. Now it cleaned it\nup. So\nwhen you see something that isn't it\ndoesn't look right usually just ask the\nmodel why you did that is there any\nalternative\nand in this case I knew that to provide\na layer in test we should just use it\nlayer so I kind of skip that\nbut in reality I would have if I didn't\nnotice I would have discussed with the\nmodel that I didn't like to see that\nrepeated thing all over.\nAnd sometimes it's necessary. Sometimes\nyou're wrong and the model is right.\nThat's the way to do it.\nIn this case was completely unnecessary.\nNo, I think we have it do the we have\nit.cribe.\nSo you would you would do it layer as a\ntop\nthing\npass the layer like layer whatever\nthen\nin the closure do it.cribe describe\ncould probably also add an describe as a\nshort\nmodels don't care about verbose code.\nWhy should we make it less verbose?\nDoes it do any cleanups?\nYes.\nYes, but you can do it per test still.\nNow\nit does poison the other tests.\nThe other alternative is you provide it\nlayer at every test.\nThe reality is whenever you're using a\ndatabase, in this case it's SQLite.\nSo the argument is kind of moot. But if\nI were to use a postcress in a project\nwhere you have hundreds of file,\nhundreds of tests, spinning up a\nposgress instance per test is going to\nmake your test runtime\ntwo days maybe. So usually what I end up\ndoing\nis I end up making tests that are that\ncan run that do self cleanup. Like for\nexample, I run a test within a\ntransaction and I roll back the\ntransaction as soon as the test finishes\nso that they are kind of atomic by the\nfact that they don't leak that\nit would be another pattern that we can\ntell the tell the model to to do. It\nwould be a matter of creating the\ntransaction and the roll back.\nBut there's there's alternatives\nand\nlibrary.\nNo, we added the the effect codebase in\na repository folder. We created an\nagents.mmd\nthat references\nthe the effect repo and then for the\nfeatures we wanted to use we asked the\nmodel to create patterns by looking at\nthe repo investigating how things are\ndone in the repo\nas kind of general knowledge. In this\ncase we did one for SQL we did one for\nAPI. Now the good point is in this\nsession we have best practices about\ntesting. So let's create\npatterns/testing.md.\nIt should include all the best\npractices\nof testing effect based code including\nusage of\nheat layer\netc.\nI also update I'm going to cue that\nagents.m MD to reference\nall the patterns\nin do\npatterns\nand the next thing that you would do to\nautomate the flow is for example\nopen code allows you to create slash\ncommands\ncode allows you to do the same.\nyou optimize for slash new pattern\nwhatever you want and um\nyou can create skills and tag the skills\nuh skills are very useful for these kind\nof things uh\nI'm kind of against skills in general\nnot for these things they are ideal but\nmany people think that just by adding a\nskill you're going to make the model\ngood at React, you're going to make the\nmodel good at Next.js. The reality is if\nyou put a skill for every single Nex.js\ninternal, you're going to pollute the\ncontext and not get anywhere. So skills\nhave very good use case, which is this\nkind of use case and I guess they are\nmore general than slash commands. So I\ntend to do slash commands because I tend\nto use a single coding agent. But\ndefinitely if you are for example in a\nteam where everybody's free to use their\nown agent maybe some people use cursor\nsome people use open code some people\nuse code skills are a good baseline\nlet's see patterns testing\nuse effect test for all effect based\ntests\nuse it all effect use it layer Avoid\ncustom wrappers\nthat call layer.build.\nThis is a very specific rule. Now, a\nfriend of mine told me whenever you you\nyou read a rule book, a legal rule book\nor you find those specific rules that\nare just like when you enter a pub and\nit's like don't do skateboarding on top\nof and you ask yourself, why does this\nrule exist? Because somebody did that.\nWhy does this rule exist? Because the\nmodel did that.\nWhy this pattern? Okay, you see relevant\nfiles.\nThey're all linked.\nYes. And\nthere's a friend of mine who's writing\num a llinter plugin that checks for\nexisting references.\nSo, when you add uh\nwhen you change code it runs the in the\nCI and says hey this reference is\nbroken.\nYes.\nThe fullome\nslash whatever. Yeah. Yeah.\nHow would you write a test for a\npattern?\nYou mean actually write a file?\nfeel like that could be a way. Sometimes\nthe code that is inside\nthe patterns is not really executable.\nI guess it has pros and cons. It's\ndefinitely an interesting idea. For\nexample, maybe with a with an additional\ntag like TS execute these\nto flag which of the patterns you\nactually want executed or like\nreferences which files you want to be\nreferenced because sometimes it mentions\nfiles as examples. For example, if you\nwrite this feature use a file called ABC\nand that's not a concrete reference.\nSo you don't want your program to fail\nbecause it read that\nThat's more more in the direction of\nevaluations. So evolves.\nYes, that's at scale. That's very good.\nI found doing it on a per project basis\nends up\nmore.\nWhat we are thinking of doing in the\neffect repo is for example to have\nevolves running once per day\nand generating reports. So anytime we do\nlibrary changes or we add more docs we\nadd more examples we see exactly\nif the outputs are are better or are\nworse. Sometimes in evils it's very hard\nlike even anthropic a while ago wrote a\nblog post\nwhere the summary of the blog post is we\ndon't really know when code is good or\nbad because\nis is more terrace code better\ndepends is more verbose code better\ndepends\nthere are some properties where you can\nsay this is definitely better than not\nLike code that type check is better than\ncode that doesn't. Probably true.\nBut when it comes to style, when it\ncomes to\nlike is this file\nstructure\nbetter than another file structure and\nthey both convey meaning, you kind of\nneed a human at the end to say, \"Yeah, I\nprefer this.\" And if you take 100\nhumans, you're going to have an 8020\nsplit.\nSo we have the same problem now with\ndefining effect patterns because we are\nrunning evils and evils are kind of our\nopinion of what's good and it's not\nreally\nan absolute truth. Let's putting it\nlet's put it this way.\nWe have\nhumanly written best practice codes.\nWe have generated code and then we have\nan LLM that matches and says is these\ntwo different or not? Give it give us a\nscore. And that's pretty much how you\nrun the EVO. not very not a very nice\nway to run but we're trying to figure\nthis out because we are thinking of\nfine-tuning the model on top of effect\nand for the reinforcement learning part\nwe are going to need to have good\nevolves.\nSo\nit's part of what we are researching\nright now.\nThere's no right or wrong answer.\nIf there was all the models would\nperform would perform the same because\neverybody would have the same evils,\neverybody would have the same thing. But\nnow we have all the patterns for what we\nwant. So I feel like we're at the point\nof saying commit this.\nI'm going to create a repository and\npush it\nso that at least you have access to it.\nGosh,\nI'm too big.\nNew repository.\nIs it public?\nPlease choose an owner. Sure.\nAdd more orange\nand push\npushing the final repository. So\nhopefully\nso we haven't got to the point of doing\nclustering and workflows.\nJust sharing a few words about why you\nwould want those aspects in your code.\nThis is a very dumb to-do API. One thing\nI wanted to add\nwould be authentication and\nregistration. For example, when you have\na registration, your process is usually\nwrite something in the database and then\nsend an email\nor send an email code and wait for\nconfirmation.\nAnytime you do two unrelated operation,\nthere is no transaction between them, no\ndatabase transaction between them and\nyour server may fail at any random point\nwithin your code. So it's very hard to\nguarantee that the email has actually\nbeen sent which is why many time in a\nregistration procedure you see the\nsentence\nif the email did not arrive in 30\nminutes please retry\nyou retry for me why should I retry if I\nhaven't received the email that's the\nthat's a symptom of a of a badly\ndesigned system that cannot guarantee\nthat two operations happened\nto do that you have various ways. One\nway is to implement cues and so on and\nso forth. The other way is to use\nsomething like workflows. You have\nsolutions like temporal ingest. There's\nmany workflow solution. effect has one\nuh implemented on top of what uh what is\ncalled effect cluster where basically\nyou run a cluster of ban node whatever\ninstances and the system itself\nguarantees that once a procedure starts\nit's going to finish even if the server\ncrashes it's going to move to a\ndifferent uh location how I would go\nabout it same way as I did now uh ask\nthe model to explore the the repository\nextract the best the patterns around how\nto use effect cluster, how to use effect\nworkflows and u just\ngone from uh from there. It's very\ninteresting. Uh it's still in the\nunstable part of effect but it's going\nto be stable very soon. And uh we think\nespecially with um if you do\nif you integrate AI in your app\nit's going to be even more important\nbecause with AI every process becomes\nmore long running like LLMs takes\nminutes to answer. There's a lot of\nthings that can go wrong in a minute. If\nthe average response time is 10\nmilliseconds\nserver is pretty much never going to\nfail in that 10 millisecond. If that 10\nmillisecond becomes a minute, yes,\nyou're pretty sure the server is going\nto fail in that minute at some point.\nAnd usually\nbefore the companies that would use\nworkflows where larger scale companies\nbecause at scale every edge case happens\ntwice per day, uh with longer response\ntime, even even if you have 10 users,\nyou're pretty much going to have\ndisruption.\nIf your average process takes a minute\nand you're going to have failure all all\nover the place which is why for example\ntemporal became much more interesting in\nthe in the past 12 months because\neverybody's now implementing AI in their\nown products. So they have chat bots,\nthey have uh any kind of AI AIdriven\nprocess and with the fact you get\nworkflows, you get clustering, you have\nAI integrations,\nyou have discord, slack integrations and\nso on and so forth. So it's system is\nreally composable and\nthe models are pretty decent on it. We\nhave a working API.\nI've been\nspeaking for about an hour and a half\nand\nI started with zero fat knowledge. It\nwas an empty repository\nand this is why I wanted to call this\nworkshop just clone the [ __ ] repo.\nThat's pretty much it. Uh if you have\nany question or anything else, I'm happy\nto discuss uh with you at a later point.\nand let's get the next speaker set up.\nThank you so much.",
  "transcript_chars": 48225,
  "ingested_at": "2026-05-12T00:31:42.461264+00:00",
  "source": "channel",
  "yt_meta": {
    "view_count": 7577,
    "like_count": 169,
    "channel_id": "UCLKPca3kwwd-B59HNr-_lvA",
    "categories": [
      "Science & Technology"
    ],
    "tags": [
      "ai",
      "ai engineer",
      "ai engineering",
      "software development",
      "tech",
      "startups",
      "software architecture",
      "machine learning"
    ]
  }
}