|
|
|
20:35 |
|
|
transcript
|
1:37 |
Welcome to Agentic AI for Python. I'm Michael Kennedy. I'm going to be your instructor for this course and your guide along the way. I am incredibly excited to share Agentic programming with you in Python. Look, I get it. There is a ton of hype. A lot of people are tired of the AI thing. It's in every email client. Who knows? You probably have AI in your refrigerator these days, and who knows what value it adds? Probably not much. But this agentic programming, these agentic tool-using programming AIs are unbelievable. I have had unimaginable success just five years ago. It's truly unimaginable that there are tools that are this good that make you this productive. And what we're going to focus on in this course is how you, as an experienced developer, can take the most advantage of this. Not vibe coding or any of that buzzwordy stuff. No, applying software engineering, using these AI tools as helpers along the way to build incredible solutions and applications and features. I hope you're excited. I'm going to try to show you, try to convince you how awesome these are by showing you many different concrete examples. And we're going to build out a couple of applications throughout this course. I think if you've not seen this before, I'm sure your mind will be blown at the end. You're in for an amazing ride. We're going to have a great time. I'm looking forward to sharing it with you.
|
|
|
transcript
|
4:36 |
Let's jump right in. What is agentic AI in regards to programming tools? Well, agentic AI, and this is mixed in with tool using AI, is an entirely different category of what you might have experienced before. Definitely if you've used things like chat or GitHub copilots, super charged AI, auto-charged, auto-complete type of thing, that is one thing. What we're going to see this course is wholly a different thing, a whole entire different level. You've heard that AIs hallucinate. You've heard that they can't write good code or they always go off the rails. I think you'll be surprised how on target they will be and how effective they will be because we're using this agentic tool using AI rather than just an LLM chat or a really powerful autocomplete. Let me show you. What we're talking about is absolutely not chat. When ChatGPT came out, it was truly groundbreaking and it still every day completely impresses me. However, it is not what we should be using for programming. Let me give you an example. Here I have just went to the Talk Python website and just selected a bunch of the table that lists all the episodes. And I said, hey, give me a regular expression that will parse out all of this information out of the table, give me the number, just the numerical integer value, and the title. And he said, no problem, Michael. I'm on it. 37 seconds later, he says, here are a couple of really excellent regular expressions you can use. So I said, all right, well, let me try that. And I fired up Python, and I pasted in the text in the regular expression, and then I and look at that. Incredibly, incredibly, it is correct. This is mind-blowing. It's not a, hey, I found a regular expression and it might work. No, it read the data, understood it, and gave us an exact regular expression. This is so impressive, but this is not what you should be doing. What is wrong with this? Well, look, I took some unrelated code and data and I said, I need this thing. Then I got a little fragment back and then I went and moved it over to my app or my Python REPL. And I said, well, let's work with it now. It doesn't understand everything that my program is doing. It doesn't know how to talk to my database and see if the thing it actually built is consistent with the models that are stored in the schema of the database and all of these different things. It just, it only knows a little bit. It's super impressive what it can do with that little bit, but it doesn't have enough context and understanding and even the ability to verify itself. It just gives you the answer. It says, I looked at it. Here's your answer. Good luck. Did it try it? Who knows? Probably not. And if chat's not the answer, I guarantee you this crazy overdone autocomplete stuff that we get from so many of the tools these days, that's not it. Look at this. Our cursor is right here. And we haven't even written a word. Oh, you know what? We're going to write. Return. tbody we're going to loop over the users and map them to the rows and then we're going to loop over the columns and map them to the tds and that's impressive until it's not turns out I don't know how you feel about this I hate this stuff in my code in my editor it drives me crazy why because it's 95% right or 90% right which is amazing but how do I what do I do here let's let's suppose that the class name is wrong. And that the thing I'm mapping into for user bracket column, I want that slight, maybe it's user dot attributes of column. So I could either accept this and then go find the few places where it's wrong and adjust it, or I could just type it out. But this auto-complete's constantly bouncing around in my way trying to do more, but you can see that what it's doing is wrong, but it's mostly right. And it just takes away from the art of coding it, it's in the way, right? You've got to like kind of power through it and ignore it if it's wrong. You want to accept, I don't know. It's just, it's not good. And this is not what I'm promoting. In fact, most of the time I turn these kinds of features off even when my editors have them. I want basic auto complete. I hit dot. What are the attributes or functions I can call there? That's all I need.
|
|
|
transcript
|
8:43 |
Now I can talk all day, but in order for you to appreciate this, you really need to see it in action. And what we're going to see is a couple of animated screenshots of this AI working in action. And then we're going to go build it out and go round after round of actually doing it and guiding it and tweaking it and really leveraging this. But I want to give you a quick glimpse before we jump in. Okay, so let's look at an example. Let me give you a little background on what the feature I'm trying to build with this example. Over at Talk Python, we've got a bunch of structured Flask routes that generate different things. So for example, when you go to an episode, there's a specific route in Flask that handles that, and it's data-driven in all of these things. There's one for the RSS feed. There's one for the list of episodes. There's many, many pages. It's a very much larger project than you would think from the outside. But on top of that, there's a fallback CMS. So if you request a page and it's not one of the particularly hard-coded ones from Flask, then it falls back to this database-backed CMS that we have. And in there, it says, okay, this URL, do we have, is it supposed to be a redirect over to a resource or an advertiser's page? Or is it supposed to show some particular content that's just coming out of the database? Those kinds of things. If all of that fails, if it's not a data-driven programming request, if it's not a CMS request, then it's something that's missing. And we record that in our database to say, we want to know what pages people and sites and Google and so on think exist. And maybe if it's really, really popular, we should just create it. If everybody keeps saying /rss when it's actually slash episodes /rss, well, maybe I should just add RSS as a thing. So the feature that we were going for here is to create a visualization, an admin front end to allow us to do a bunch of different things with those missed CMS requests. All right, with that stage set, here's what I wrote, and let's watch it go. Think about how different what you're about to see is than I pasted some data in chat and I said, hey, chat, do this. So here's what I said. We have our CMS service recording when a URL is not registered and we have to return a 404. This appears in the log files as a CMS service colon, whatever, right? Recording missed CMS page at some location. I want to add a new section to the admin area that will put all the CMS misses that are not skipped or suppressed database we can say yeah I know this stop bothering it just get it and just ignore it I want to display this in a table with searching and ordering I meant sorting but whatever right so this is what I said and you can see it has that little one it actually is looking at the editor but it's also running in the context of the application so it can it knows our entire code base and all of our tooling and our virtual environment and so on what happens when I hit go starts out and says great I'll help you section to the admin area to display the CMS misses. Let's start by exploring the code bases to understand the current implementation. Looked at the CMS service to see what it's doing when it has a miss. It looked at the admin area to see how those pages are structured. Great. I'm going to need to add a link from the admin landing section to this area. So let me look there. All right, great. I got that. Now let me look for a more sophisticated example of a table that you might be using. Oh, we have this blob management, like an S3 sort of front end type of thing in the website. That has a really interesting table. That's a good match for what it's trying to build here. So it's like, all right, that's great. We'll maybe use that as a template. Now we want the filtering, sorting, other types of interactions. So let me look at the JavaScript file to see how the other table was doing that. Now it's got all the information. Instead of just jumping into it, It says, I actually broke this problem down into a bunch of small pieces. What would you, as a developer, do? You would break the problem down into small pieces. I've got to create the page. I've got to create the table. I've got to create the JavaScript. And then we're going to tie the JavaScript together, et cetera, et cetera. That's just what it's doing. You can look through all these different to-dos that it's done. It said, all right, let's jam on it. And off it goes. Maybe 10 minutes later or so, I'm not sure. It had pulled off all of these. And I don't want to read the whole thing. We're going to do a whole bunch of examples of this live. But it did all of its steps one after another, verifying along the way. And then it said, oh, look, I'm done with the code. And so I'm going to run the Ruff formatter against your code. Because I know you have a ruff.toml file, which specifies a configuration, how you like your code. So maybe I wrote it one way, you like it another. We're going to make sure whenever I write code, says the AI, that you're going to get it the way you like by me formatting it with your config. and sure enough at the bottom down here you can see two files reformatted. So it did convert it over to the way we like, which is amazing. But it's not done. It's not like here is your answer. It said, let me just make sure everything's hanging together. And it looked, it said actually Pyrefly, the type checker you're using, seems to be surfacing a problem with this update query bit when we're trying to interact with the database. I think this is when it's when you say here's a miss, but I want to suppress it or hide it. Basically, this has got to update the database. And it noticed that when it wrote that code, there's some kind of issue. We're using the Beanie ODM talking to MongoDB. And look at this. It said, Hey, I went and I looked at the Beanie documentation for how this is supposed to work. How does it know about the documentation? We'll see later. And it goes and it finds the documentation and says, oh, I see this returns such a thing. Let me see how you're using it throughout the app. It says, oh, it looks like actually there's a bunch of places where you're already calling update and that's working correctly. It turns out the problem is with the type stubs for the ODM and not your code. So let me just put a flag to ignore that for now. What I did later is I went back and I actually used the AI to create a better version of the type stubs based on how you actually use them. So those type errors went away globally and we save that in a place that all the editors can find, which is great. But for now, I just said, it's not really a problem. It's like a deficit of the ODM. How long was that? And if I think back, it's probably an hour end to end, playing with it, tweaking. I pulled up the UI that it gave me and I said, oh, I don't really like how this is laid out. There's a little too much padding here, not enough there. I don't like that color. And in the end, we have a super cool admin section here. Look at this. Showing 1,000, you know, it's paging, showing 1,000 of the first 180,000 CMS misses. Ooh, you can mark them as malicious. You can mark them as suppressed. It filters them out. You have a search, which is doing dynamic filtering against it. You've got all this reporting here. How cool is this? This whole feature was done almost entirely by just working with the AI. I didn't have to write much code. I gave it a little nudge here, a tiny correction there. But this came from that agentic AI. And I didn't give it that much more information than I did my regular expression. The key difference, the big difference is it runs knowing all of your code, all of your tools. It can go to your shell and run ruff. It can talk to your database. It can do whatever it needs to do as if it was a junior developer, a theme you're going to hear a lot. So this is the kind of thing that we're going to work through in different incarnations of this course. We're going to have maybe some examples where we start completely from scratch and some other examples where we start with existing code. But the results we're going to get are going to be amazing. I hope you're excited. I think this is just such an amazing technology. It really supercharges developers if they take the time to guide it, set it up the right way, and use it as a partner rather than just some thing you throw a bunch of commands or prompts at and just walk away.
|
|
|
transcript
|
5:10 |
I don't know if you've noticed, there are a lot of AI tools out there. There's a lot of hype out there. There are a lot of editors. Everyone and their brother is trying to add AI to their tools or create an AI tool so that you can use theirs and not some others. So it's not a given which tool we're going to be using. You may have recognized that little chat window we just did, but even that, it could be a handful, four or five different tools. So what we're gonna do is we're gonna use Cursor. Cursor is a fork of VS Code. And to me, if you're a person who likes a IDE type of editor experience, this is hands down the very best thing. So Cursor, nice editor, really deep integration to how the UI interacts with what Cursor does, how it controls the AI to find all the right elements project and so on. We're going to be using here, this has got a free tier as well as the editor itself is free, but to use the AI, it's got a trial period and a free tier and those kinds of things. Notable mention, the other one that I would strongly recommend if you are not someone who wants to use an editor like VS Code or PyCharm would be to use Claude Code. So a bit of a Spoiler, we're actually going to be using Claude as the model from Cursor to do most of our work, right? We use Claude Sonnet 4.5 at the time. But Claude code is more of a terminal-based experience. There are plugins for editors, but it's primarily you go into the terminal and you get this chat experience for your code in a very similar way I already explained. But all of that is happening in just a terminal flow experience, not within an editor. So if you're not a VS Code PyCharm type person, then you can use this. Almost everything that we cover in this course applies equally to ClogCode or to Cursor. Because like I said, underneath, we're using the same model. Notable mentions. What else might you choose if you don't choose those? There's some really good ones out there that you probably haven't heard of all of these. I'll bet most people taking this course have not heard of all of these. So one that's kind of new and really cool is called Cline, C-L-I-N-D-E. I'm not sure exactly. It stands for something like that. The idea is this is an open source plugin that goes into VS Code, PyCharm, and Cursor actually, though it doesn't use the Cursor subscription. It's like alongside that. It just happens to be in the same editor. And the idea here is this is an open source system and they do not charge or even really control how you're paying for your AI usage. You put your API key for like Anthropic or OpenAI or something in there and it just passes that through and it's just a tool that brings these things together. How do they make money? Because there is a pricing up there. They charge for team tools basically. but it's an open source, pay whatever you use of the AI sort of thing. So this is actually really interesting. It goes into a bunch of editors. Very nice. There's one of the OGs, which is GitHub Copilot. And you can see they just added agentic mode. Why? Because it's so much better, right? You can see right above the AI that builds with you, it says now supercharged with agent mode. Okay. We can also do kilo code, which is another open source editor, I believe. I believe it's VS Code-like. Also, you can see that it plugs into PyCharm and Cursor as well, and there's install kilocode, three icons there. And there's also Juni from JetBrains. So if you're a JetBrains Pro subscriber and you have the AI package, you can use Juni in PyCharm, which is JetBrains' own agentic coding agent. Now, be careful here. JetBrains has two unrelated, disconnected AI things at the time of recording. I doubt this is going to last, but there's a JetBrains AI, which is like ChatGPT in Autocomplete, and there's Juni, which is this agentic thing, and they don't go together. So, interesting. You can also take all of the three things, yeah, all the three things we just talked about and install them into JetBrains. And JetBrains also now has a collaboration with Claude. So there's a bunch of mixing of these things, but you'll see there's actually a lot of similarities and commonalities amongst them. So a lot of choices out there. You choose what makes you happy. But for this course, we're doing Cursor backed by Claude AI models, Claude Sonnet 4.5 and others.
|
|
|
transcript
|
0:29 |
Super quick, before we jump into the next section, I just wanted to tell you that the source code for everything that you see me type on the screen is available. I strongly encourage you to go to the GitHub repository right there at that URL. It also is in your player and on the course page and so on. And star it and consider maybe even forking it just so you have a persistent copy for yourself. So all the code that we create and all the little extras, you'll find them here. Don't worry about writing them down.
|
|
|
|
12:48 |
|
|
transcript
|
5:38 |
In this short chapter, I want to give you some concrete examples of things I've built with Cursor and Claude Sonnet. And all of these are in production, or on PyPI, or wherever they are. And they're well-structured, they're nice code, they're not just a bunch of slop. No, they're really, really good. And you'll notice a theme. Many of these are things like, wouldn't it be nice if I could, but it's way too much work? Or wouldn't it be nice to enhance this thing, but I've got more important things to do. So instead of having a multi-file drag and drop interface, we're just going to have a button that you browse to pick the file, you know, that kind of stuff. And we'll say, well, that's how it could be. But if a little work from cursor, it could be really, really nice. Or it's a feature that I'm like, I just can't justify the time because it's going to take so much time versus what you get out of it. So I want you to come into it with that mindset. Obviously, we haven't met necessarily, but I'm sure in your life as a software developer, there are things like, I would love a utility that did this, or I would love a library for that, or something over here I could enhance, but it's been there for two years, And I just, I never got around to it. You'll see with these tools, those become not things that are like a drag on you. They become stuff that are just fun opportunities. Like, oh, I got like two hours to work on something. Let's try to fix that thing that's been a hassle for two years. You probably can, let's see. All right, here is a tremendously big challenge that I had. So when I built Talk Python way back when in 2015, Bootstrap was all the rage. And boy, boy, Bootstrap wasn't brand new. No, it was Bootstrap 3. Bootstrap 3 is no longer supported. And now I have this problem. I have a ton of code written in Bootstrap 3. HTML, you know, the HTML is structured like if you want a grid layout, it's got to go container and then row and then column or whatever the grid settings that I'm forgetting for Bootstrap 3. and it's pervasive and deep within the HTML structure the way Bootstrap works. So whenever I want to add a new feature to this website now, I have to go and write old Bootstrap. This is a hassle for me because I know it pretty well at this point, but also it's just not following the modern themes. And every time I add a new feature with this super old framework, I feel like, well, I'm kind of adding more technical debt. I've created yet another thing that is out of date on this old framework, okay? I want to move to Bulma, which is kind of like Tailwind, but it doesn't have all the build steps. It's like Tailwind, but super simple. It's a utility classes CSS framework. But I've got to rewrite a ton of stuff. How much? Well, let's see here. Code stats for talkpython.fm. Not the courses, just the podcasts. For the HTML templates, we have HTML files, but mostly PT files, which are chameleon. And we have 8,564 lines of that structured, super framework focused HTML. We also have 8,000 lines of CSS. Oh my goodness. And we have 40,000 lines of Python code. That's a lot of stuff. Now the Python code doesn't have to change at all, but those 16,000 CSS and HTML lines do. And this is why for years, I wanted to move off of Bootstrap 3 to something more modern and nice and haven't. You go over to Bootstrap, getbootstrap.com, and you look at it, it says, Bootstrap 3 has reached end of life. Go, don't mess with it. You need to get away from this. And I can't even say, oh, I'll just rewrite it in Bootstrap 5, because they've changed their structure as well. It's like kind of the same problem, just sticking with Bootstrap. So there's not a great answer over there. So I want to move to this thing called Bulma. Amazing, right? So I was sitting around some summer night, sitting on my back porch, messing with my computer thinking, huh, I bet Cursor could handle this. So sat down, started working through this, and by middle of the next day, the whole project was done. And this would take a week, weeks to get right. Along the way, not only did I just make sure it transformed over correctly, I actually saw some parts. This is kind of clunky. I know that's the way it was, but let's make that a little bit better. So I completely converted this over probably in clock time. It probably took six hours, four hours. I don't know, not that long. And it's visual. It's complicated. It's incredible that this worked. So this is one of the things that's been bothering me for years. and I could never justify taking weeks of work to just rewrite the website to look the same. Could I take four hours? Yes, not only could I do it in four hours, it was fun to do it. So this is example one, just migrating from one CSS framework to another. It sounds small, but now when I make changes to the site, I'm building on modern stuff, not adding more tech debt.
|
|
|
transcript
|
5:02 |
The second one that I want to talk about is enhancing the search functionality over at the Python Bytes podcast that I run with Brian Okken. So over there, and it's like a news show, there's a bunch of headlines. And it's really common that people come and say, hey, if they talked about this, either go look what we said about it or suggest like, hey, would you guys be willing to cover this topic so that we learn more about it or whatever? It's really cool. And a little bit of a inside baseball is, I use it all the time when I'm preparing for the show because I'm like, dude, we've covered, we've done this for 10 years. Like, have we covered this thing before, maybe five years ago? Or is it actually worth covering some aspect from scratch? Or is it an update to something we talked about? So finding this, finding things through search is really, really important. This one is better seen live. So let's jump over there. So I can come over here and I can hit search. and it just says, what do you want to search for? Let's imagine I want to search for something like MongoDB. There's 103 episode results. Now, before I addressed this problem with cursor, what would happen is you would see this, number 447 going down a rat hole, and then this, none of these things down here, and then this, And it was just a flat list of episodes which had that search result in it. It's better than nothing, but it's not that great. So what did I do? Here's a couple of things that I said would be nice, right? I would like to elevate the episodes where MongoDB is actually mentioned as a direct topic. It's either in the title or it's one of those, right? So there's a bunch of, you can see like this one right here. Now we have this little highlight. It says, this one, you actually talked about the Django backend for MongoDB, rather than it's just some other random match. If you just saw the title, nothing about this tells you that it stands out from the others, right? So I added this UI element here in this functionality with cursor that says only show episodes with direct topic matches. Look at this. Now, instead of, what was it? 103 results, it's 11. And you can see, look at those. How awesome is that? And even better, watch this as part of what Cursor helped me do. Official, so if I click on this, it doesn't take me to the resource, it takes me to the conversation on episode 90% done 50% of the time. And it actually takes you right to that portion of the podcast, right? This is exactly why this here, here's all the stuff we said, all the extra resources, not a ton of links, but migrations and models and so on. Okay, this is a massive improvement, a massive improvement. How long did this take? From, hey, wouldn't it be better if we could show more stuff to changing the search results, to showing these things, to there's a whole performance story about this, right? Look, you saw 103 results came back here. Let's search for something else. Turn on the dev tools. Let's search for something like Django popular oh there we go there's a little filter so let's see if we look at this example here what was it how long did it take 750 milliseconds or this MongoDB one was even quicker it took 84 milliseconds and let me run the Django one again 400 so you can see actually this thing here the second request for Django took half as long and going forward that result is going to take only half as long because not only do we add this ui feature but there's a ton of really interesting performance enhancements and caching using something called disk cache that's really incredible so that like the parsing and rendering of all this information like what do the topics of that look like they started as markdown and they end up looking like this and from the database so a ton of features how long did this take me from idea to finish with the UI, all that, 45 minutes, maybe an hour with like a little messing around and getting a coffee or something. That is crazy to look at that and go, wouldn't it be nice if our search were better and think, yeah, but it's not that important. And it would take a couple of days. If it took 45 minutes, you know, the calculation starts to change. You're like, you know what, 45 minutes to have this over what we had, 100% I'd do that all day. It was fun because it was cool to see it all just coming together so quickly and to like iterate and try all these things and learn about some of the caching that I pulled off. So really, really interesting ideas here. And just another example, like this is in production. You can go play with it.
|
|
|
transcript
|
2:08 |
Last but not least is a Discord community. Well, with Discord, you want to have a pretty deep integration with things like who is a member, who is not, what's happening in the podcast. So, for example, these days when I go and I'm about to start a podcast recording, which we're live streaming on YouTube, it's basically a single CLI command that will then notify all the different locations, including the Discord community. like, hey, in 20 minutes, we're starting a Discord or a YouTube stream with this guest, with these topics, you should come and join, right? Making the membership and the community a little bit more tightly together, a little more cohesive. So I got to write an entire Discord bot to make that happen. I've never created a Discord bot, but guess what? It's pretty much Flask and Python, and there's some nice libraries. And Cursor and I, we got it completely working. You can see right here, you've got the bots. I can just go and ask for the bot status. It's online and ready. It's got a 16 millisecond latency, which is pretty good. This one's been running for 23 minutes. It cycles every few hours just to keep everything fresh. All this information, all this Discord bot stuff, completely built hand-in-hand, me and Cursor and the documentation. So that's it. amazing concrete things built significantly with the tools and techniques that you're going to see throughout this course. And a lot of my working with this has evolved and iterated and improved. Like that used to work, but I can do so much better. So I hope this chapter has inspired you to look at like, okay, I see how that can, that can make sense in my life, right? That, that looks a little better than I expected of just going into chat and saying, hey, chat, give me a regex. Or going and just auto-completing your way through with overwhelming and not always right auto-complete. These are all meaningful features that took lots and lots of work and saved way more developer time than we spent on them to create them.
|
|
|
|
1:03:34 |
|
|
transcript
|
1:43 |
It's time for us to dive in and start programming with Cursor and agentic AI and Claude Sonnet and all the things. We're going to put much of what you've seen into action. You've seen some really cool examples of things that I built that are in production or being used widely that are working great. It's time to see how to go from zero to finish with that. Really quickly before we get to it, though, I want to just set some expectations. For some reason, a lot of people seem to get frustrated with AI if it makes a mistake. I want you to think about this little AI programming helper of ours as maybe a junior employee. Better than an intern, not quite a senior software engineer, but whatever they are, they're incredibly fast at what they're going to be able to do. So you would never hire somebody and expect absolute perfection from them in their creative endeavors. So I think we need to have the same perspective on AI. Don't get upset if it gets a little thing here or there, not quite right. If it gets 95% of what it's doing correct and you've got to work a little bit with it to get that last bit done, amazing. That's as good as a junior developer who you've given vague specifications to and you go back like, pretty good, but this is not actually what we're looking for in this part right here. So just set your expectation. If we get it almost all perfect, that's actually incredible. That's all we'd ask from an employee or a teammate or something like that. So just keep that in mind.
|
|
|
transcript
|
1:01 |
|
|