Video: Agent Harnesses & Deep Agents 101 | Duration: 2808s | Summary: Agent Harnesses & Deep Agents 101 | Chapters: Welcome & Introduction (2.72s), Agent Architecture (93.025s), DeepAgents Introduction (216.86s), Human in the Loop (366.405s), Offloading and Summarization (492.58s), Skills and Sub-Agents (722.1s), Production Features Overview (962.725s), Model Connection Setup (1125.05s), DeepAgent Harness Basics (1218.335s), System Prompts (1396.27s), Creating Custom Tools (1563.625s), Short-Term Memory Management (1739.05s), Human in the Loop (1897.235s), Sub Agents (2222s), Sub-Agent Delegation (2365.76s), System Recap (2491.255s), Practice Exercise (2561.065s), Upcoming Workshops (2648.205s), Closing & Thanks (2695.435s)
Transcript for "Agent Harnesses & Deep Agents 101": Hi, everyone. Thank you so much for joining us today for this session of agent harnesses and deep agents one zero one with Langchain. I'm Giselle. I'm the education marketing manager here at Langchain. And joining me today, we have Jess Wang, who is an education engineer at Langchain, and she'll be walking you through. I will be in the back answering any questions that you might have. So feel free to use the q and a tab or the chat to put in your comments, your questions, and we'll also sprinkle in some poll questions like this one, throughout the presentation. And, let's get started. Yeah. So to start, whoever didn't pick line graph, we're keeping an eye on you because that's the wrong answer. But... Okay. Let's get started. Giselle, could you allow me to screen share? Okay. So welcome to agent harnesses and deep agents one zero one. Thank you so much for joining us today. I see some messages from all over the world. My name is Jess. I'm an education engineer at Langchain, and we have a couple others behind the scenes helping you. So feel free to drop anything in the q and a as Giselle mentioned earlier, and we will try to answer your questions as quickly as possible. So today, we're going to go over the basics on DeepAgents and actually build one together. There will also be a take home assignment you can work on later to customize your own deep agent. Now let's start with what is an agent. Well, one definition is a model calling tools in a loop until it completes a task and returns a result. You've probably used Claude or ChattoptyPT and seen it searching for tools while it tries to answer your question. This is that. So you have your input, which is your question, and that goes into the model. The model then calls a tool, and then the tool result goes back to the model, keeps looping until finally you get your output and answer. So this is the entire picture. An agent is just a model calling tools in the loop until it completes the task. And this tool part here is part of something called a harness. And to define what a harness is, let's take a look at this again in the context of an agent. Another definition of an agent, to simplify, it's just a model plus a harness. The model is a large language model, and the harness is the scaffolding around that model. To break that down visually, the model here actually can't do much on its own. A large language model is technically just a word guessing machine. The harness here is what surrounds the model, and this includes things like tools, sub agents, the system prompt, and so much more. All of this combined is what makes an agent. Now you've maybe seen the memes about just asking Clot or ChatGPT to just make no mistakes, but it's not enough to actually just tell the model that. A good harness is supposed to enforce the behavior that we want so that it actually makes no mistakes. So a harness makes sure the model makes the right decisions by getting the model the right context at the right time for the given task. With just the LLM, you're missing all of these support structures. Now the harness provides many things that improve your agent over time. Agents need to work in an environment where they can take action. They need to connect to your data. They need to manage growing context over long runs. They need to parallelize tasks, connect with the human in the loop, and so much more. All of this to improve your agent over time. Now that brings us to the question of how exactly does DeepAgents fit into all of this? Well, DeepAgents is LinkedIn's opinionated harness. What this means is that our engineers have built up features with the best practices so that you can improve your agent more efficiently. It's basically a customizable agent harness purpose built for complex real world tasks. Now it's a great harness for many reasons, but the first of which is that it's provider agnostic or model neutral. New models come out all the time. It genuinely feels like I'm hearing about something new every other week. And with a model neutral harness, it means you can swap in and swap out whatever model you wish without having to rebuild everything else. This way, you're not tied down by a specific vendor. So if there's pricing changes or if you just wanna use a different model, you have the freedom and flexibility to choose without rebuilding your entire stack. And that is another reason why DeepAgents is highly customizable. These customizable components include an execution environment, which is made up of code interpreters, sandboxes, and file systems. These take actions and connect to your data. Then for context management, we have skills, memory, summarization, context offloading, and prompt caching. I'll cover a few of these techniques later since they're actually very crucial for long running agents. And our harness also ships with delegation capabilities. As workloads increase, work needs to be distributed, and planning and sub agents help with that. We'll actually look at sub agents a little more in the demo later. And finally, human in the loop is built in with middleware. So sensitive tasks like financial transactions or sending an email externally get human feedback and approval in real time. You want human in the loop for things that you basically just wanna keep an eye on. You don't want things to go out without having a double check of things. Now this seems like a lot of information all at once, but we will go into this in detail, so don't worry. Deep engines is also open source, so everything that you see quite literally could not get more customizable. And most of these are implemented with something that we call middleware. Now middleware, they're essentially hooks that allow you to customize behavior within the agent loop. So middleware is a custom function that you insert into the loop, and it could go before an agent, it could go before the model, or it could wrap a tool call. It can actually be any of these things because all of these are potential middleware options. Now let's put that into context. I think it's easier to understand it this way. We'll do that with human in the loop. So you start with your input, we saw this before, which goes into the model. But instead of a direct tool call like we saw earlier, you see this person icon here in purple. That that represents human in the loop. Where normally you would just have a regular tool call, now there's a checkpoint. So let's say the tool you're trying to call actually deletes files. This is something you wanna be very careful with and have a second look at. Well, with human in the loop, at this checkpoint, you can approve, edit, respond, or reject it. But let's say we approve here. Then the tool call with the approved response is loaded back into the model, and finally, you can proceed and get your output. So this is the whole picture with human in the loop. Human in the loop specifically uses middleware that wraps a tool call because we're stopping the tool from going through by letting it have your say in it first before it just continues. And this is the same process conceptually that we saw earlier. Okay. Back to the different parts of the deep agent's harness. Let's take a look right now of some context engineering techniques. This is a really hot topic right now because if you give a model too much information, things like history, noise, or tool output, the model gradually declines in accuracy, recall, and reasoning quality, something you may have already heard of as context rot. Summarization and offloading here are two such techniques used to combat context rot. So as your agent works, context naturally will grow. This is the graph that you see trending upwards. Now context offloading explains these smaller white drops. These small drops are about managing the information that a tool returns, and this big blue drop is summarization. The harness at this point condenses the overall buildup of context while preserving the key information needed to continue. If this seems confusing, don't worry. We'll look at it in detail, and it'll make more sense. So offloading works by wrapping a tool call. So let's say a tool call comes back with something huge. You've scraped something and now you have a full database export, which could contain hundreds of search matches past maybe 20,000 tokens. This is too big and not relevant to drop straight into your model's context window and part of your conversation. You don't need all that information. So before all of those results get added to the model's context window, file system middleware intercepts it, and it writes that complete result to disk untouched, full, and lossless. So if the agent actually ever needs this full set of data, it can call the read file tool and page through just the part it needs. But what actually lands in the model's context window and what you'll keep using as you chat is just a short preview. Think just the first and last few lines plus a pointer to where the rest lives so we can go back and find that information, but only when necessary. And it's the same idea for an oversized user message, something like a long pasted doc or a long transcript. The threshold is a little higher here at 50,000 tokens instead of 20,000, and it's saved to a different folder, but it's the same concept. Now summarization, that big blue drop, works by wrapping each model call instead of a tool call and can rewrite the message list first. So on the left here is your context window, which represents everything that the model can currently see. As a conversation runs, messages will naturally pile up. User turns, tool calls, tool results, and this bar right here at 0% right now represents this. So the default summarization threshold with DeepAgents is 85%, but you can actually customize this to be whatever you want. So we start chatting, and you can see the bar going up in green right here until we just cross the threshold. So before the next model call, the harness will decide what to keep as is and what to fold into a summary to make more room. Now the reason it actually overshot 85% to 88% is because the check only runs right before each model call. And you can have a turn which has several tool calls in between and that adds a lot of context in between model calls. But everything above the cutoff here goes to a separate LLM call that writes one compact summary. And then everything below the cutoff will stay exactly as it was. So like offloading, the original messages are saved to a file, so nothing is technically lost that you see. But the next model call... See how much smaller that summary box is? It's much smaller, and usage drops way down, almost like giving you a reset button to keep going. And then the the model sees the summary and then the recent messages word for word. We keep the recent messages verbatim because if you're currently working on a task, you are going to want all of the most recent information. But something that you were talking about ages ago, maybe even a different project, is not necessary for your model to have top of mind. Now as the conversation continues, it climbs again. So what you're seeing now is the context window after summarization has already occurred once, and more messages keep building until it hits the threshold again. And we summarize again. And this time, the summary includes the previous summary as well, and then the recent messages come along after it. So this keeps cycling. It's a process that keeps going and keeps compressing. So to recap, offloading intercepts input before they even enter context, and summarization acts on content already in the context window. Now if you're a visual learner like me, I like to learn through memes, and this is how I would picture it. One stops it before it enters the context window, and the other deals with it once it's already in there. Now another context management technique is to use skills. A skill, you might have heard about this before, actually, it's basically a folder filled with the context that an agent needs to complete a certain task. For example, if you're trying to submit an expense report with a very specific format, this folder can include those instructions, scripts, and any reference docs. And it follows a very similar idea to offloading where, basically, we wanna keep information out of the context window until it's necessary for the task at hand. And it does this by using two middleware hooks. First, before the agent starts, it scans the skills folder and reads just the header of each skill dot MD file, which has just the skills name and a short description. We don't have any of the instructions on how to actually execute the skill yet. For example, something like this. These are just three skills in a folder. So we have, submit expense, write email, and prep meeting. You're not using these all the time, so it's good to keep them in a skill file because you only pull them in when you need it. Now for the second middleware hook, on every model call, it'll add that list of skills to the system prompt. This way, the model always knows what's available, but not necessarily what's inside them because it only has the name and description of the skill. The full instructions will only come in when the model decides a skill is relevant, and then it reads the file with the read file tool. Now the instructions are loaded into the context, but do you see how the other skills remain with just the name and description? This concept is called progressive disclosure where the model basically sees a menu upfront but only pulls in the full recipe when it needs it. So 10 skills will cost about as much context as ten one liners. Okay. We've covered a lot so far. We've done three examples of how to deal with context rot. But, actually, another excellent way to manage context is with sub agents. So, again, you start with your input, which goes into the model, and your model has one context window, which we've been talking about, and this fills up. But that's where sub agents come in. Think of these as mini assistants with their own context windows and separate tools. So say your main agent is a newsletter agent in charge of putting together an entire newsletter every single week. Let's make the sub agents here specialized in research. So the one on the left, sub agent a, has specific tools to scrape the web for news articles, and then the sub agent on the right, sub agent b, has specific tools to scrape through video information. We're giving them their own special instructions. They call their respective tools, and then they just give the final answer back to the model. The model doesn't need to know the nitty gritty of which tools the sub agents called or how we went about their task. It's not really relevant to the bigger picture here. And furthermore, because the sub agents are working on usually smaller, specialized tasks, you can usually use a cheaper model to do these tasks. You don't need to use Opus or Astro or whatever it is for your sub agents when you really wanna save that for your main agent. Anyways, now that the model only has the main info it needs, it can generate the final output with so much less noise cluttering its context window because it stays with the sub agent and never enters in the first place. Now if you've seen the double wears Prada, then this is how I would picture it. You wouldn't bother Miranda Priestly with menial details. As a subagent, you would simply get the model the important final information without the boring details. And since sub agents are highly customizable, you can build whatever suits your needs, including having sub agents run-in parallel. Alright. Back to our original slide from way back. As for how DeepAgents is production ready, there are so many challenges that come with deploying an agent to production. These are just to list a few. And that's actually what managed deep agents handles. I won't cover this in detail in today's talk, but as a very brief overview, managed deep agents deals with scaling in production. So from durable execution and streaming to sandboxes, schedules, MCP connectors, and auth, these are all taken care of so that you can deploy in one CLI command. But let's focus back on DeepAgents, which is actually the core agent harness. To ensure agents work with real data durably, DeepAgents adds virtual file system support. And to ensure agents can write and execute code safely, we provide sandboxes. Further than sandboxes, we also provide file system permissions and middleware hooks so that there are multiple safeguards. So for example, human in the loop, which is what we looked at at the very beginning, that's one of them. And to ensure agents remember and access knowledge properly, we have memory, skills, and MCP. To complete long horizon work, we have built in context we have built in context management techniques, of which I covered a few like offloading and summarization and skills. And finally, to optimize for provider and model choice, DeepAgents also ships harness profiles. So these are per model overrides to the system prompt, toolset, and middleware. So the same harness could perform well whether it's with Claude, GPT, Gemini, or an open source model like NVIDIA's Nemotron, whatever it is you choose to use. Okay. I've done a lot of talking, but let's get to the fun part. I'm going to demo building a journal deep agent with all the things that I just mentioned. Feel free to take a look at the collab. I believe this was sent out earlier in the email, but it might be easier just to watch me and follow along because there will be a separate take home assignment for you to play around with afterwards to practice your skills. So let me screen share the... Alright. Hopefully, everyone can see this. But, yeah, I was not kidding when I said a journal agent. We are going to connect with our feelings today because mental health is very important. So this notebook essentially builds a journal agent, and by the end, it'll be able to log and read journal entries, tag mood with sentiment analysis, remember conversations across turns, and also pause for approval or rejection before acting, human in the loop, and also delegate to specialist sub agents. All of the concepts that we covered earlier in the slides, but now a little more concretely with code. So this is just to wrap the text to make it easier to read, so just to make it pretty. Now our first step is we need to connect our model. So after you install your libraries, over here is where you get to see how things are model neutral or model agnostic. I'm using Anthropic to demonstrate here, but you can use whatever you want. If you wanna use a... OpenAI, all you have to do is change these lines. Super simple. You can use an open source model, whatever it is you like. Very, very simple. Now you'll want to add your API key into secrets. So I'm using Google Colab, but I will also send out, the GitHub repo for this. But you'll click on this little key button, and then you click add a new secret, and then you add the name here. You wanna make sure this name and this name match because that's how it finds it. And then all you'll need is your API key. I'm pasting here. And then remember, you have to give your notebook access. If you don't turn this on, that's not gonna work. Great. So all we have to do is run this. And down here is where you specify the specific model you wanna use. So if you wanna change your model provider, you change it up here. But if you wanna change the specific model, you do it here. Again, super simple, two line changes. Now the harness, which is what we've been talking about this entire time. But to reiterate again, every deep agent starts the same way. You start with a model wrapped in a harness, and this harness already knows how to read and write files and plan and call tools before you've added anything. We've built this in for you out of the box. So this line is actually how it all works. You import your library and then here, create deep agent. It's that simple. And then this model equals model is beautiful because what this means is that you can change whatever you want up here even after building your entire agent, and this does not need to change or the rest of your code. Super simple. Okay. So here is my message, my input into the agent. So I'm telling it to start a journal markdown file, to log a new dated entry from these notes, what I learned today, caching bug was hiding somewhere, how I felt, I was very relieved to ship it, a little anxious about something. And then what's next? To write better tests. And then I'm asking it to read the file back to me. So this is my input into the model, and then we invoke our agent with agent invoke and our message. Alright. So don't worry about this big chunk. If that scared you, that's just Anthropic's signature. It's very ugly. Let's just ignore it. But this human message is exactly the same thing as what I had here. I'm just printing it out so that you can see it neatly. So human message is what I put in, the input into our model. And then if we take a look, the first tool call was l s. It's trying to find this directory, but we haven't actually created any of these journal entries yet, so no files found. This is what you're seeing happen behind the scenes with the tool. So it tries again, and now it calls write file. Now if you remember earlier here, there is no write file tool. That comes out of the box, so you don't even need to say anything and it's automatically there. So now it's writing our journal. We've got the date. We've got what I learned today, how I felt, and what's next. So here's our first entry. There we go. And then because I asked it to read that file back to me, it's reading the file. It's got 12 lines and our content. And this AI message is basically what you would see if you were using any other chat UI, Claude, ChattyPT, whatever it is. You usually just get that. You don't even... Okay. So you send your input, and then this is usually all you get back. You just get this final, plain language summary of what your agent has done. So this, you get to see all the behind the scenes of, like, the tools it's calling, how exactly the model's working. But... Yeah. So this is what we have without touching anything at all, the base DeepAgents harness. That's not very fun. Let's change it up a little, and we can do that by setting a system prompt. Now the system prompt is basically a way to control how your agent behaves on top of whatever instructions or facts you give it. And it's sent to the model on every call, so it will always have this. So I always think it's very fun to do this with a very dramatic persona. So here, I'm setting the system prompt for my agent to be a melodramatic Victorian child. It's going to narrate everything with excessive despair and flowery dramatic language because I am also a dramatic person. And all you have to do after writing your system prompt is to add it in to your deep agent. You can choose to do anything else. So you can do toddler, pirate, whatever you like. At a recent conference, someone made their agent a grumpy, Jamaican auntie. He was Jamaican for context. So he had his agent scold him. So that is also an option. But here's my message. Log a three sentence journal entry from these notes, again, what I learned today, how I felt, and what's next, and then I invoke my agent. So let's see what that does. Here's my human message, my input that you saw. Scary signature. Also, it keeps trying to find this file. It doesn't exist, Claude. And then it writes the file with a very dramatic voice with great and shuddering surprise, that wicked little caching bug, shadow depths of the retry logic like a goblin hiding. So extremely dramatic way of finding out how your day has gone. But as you can see, it's written this journal entry. And even the the model's response also has this persona. Now while this sounds very silly, it's a very easy way to demonstrate and visually see how this has happened. But a more realistic use case of having a system prompt is for branding guidelines or specific voices. So if you need something to fit a specific tone that your company uses, the system prompt is great for that. And even better, you can also use the system prompt to set topic constraints or domain constraints. What I mean by this is, let's say you're trying to build a company chatbot. You don't want people using your company chatbot and wasting tokens on questions that have nothing to do with your company. Let's say you're a fast food company. You don't want people asking about shoes. You can set a topic constraint right at the very top of your code right here. You are an agent that only answers questions about fast food. And that way, it'll stop wasting tokens trying to answer questions about unrelated topics. So there's actually a very realistic use case for this. I just like to keep it fun. Alright. So that's one example of how to switch things up, but another is using tools. So I'll go into what a tool even looks like in the first place. So a tool is basically just a plain Python function that the the model can call. And adding this, this little at tool symbol, which we call a tool decorator, turns it into a tool. So the name and docstring of the tool essentially become the tool's description, and this is how the model decides when to use it. And then the type hints become its input schema, which are the arguments that it expects. And then finally, the return value becomes what the model sees back. This is easier to understand with a real example, so I'll show you with this. This is our tool. Super cute. Just a couple of lines. This is a word count tool, which, very obviously, counts the words in a piece of text. So this is the name and the docstring, and this lets the model know what this tool is and its purpose. Now here is our actual code. It just splits the text and counts the number of words. All you have to do is add this, and this is now a callable tool. So this is a very boring example, so I want to show you something that's a little more fun. Down here, we're going to do a mood tag tool. So it's going to analyze our journal entries and tag it based on sentiment analysis. So in order to use this mood tag tool that we just created, all you have to do is add it here because tools just takes a plain Python list. So if I also wanted to use our word count tool, I could just put a year word count. I'm not gonna do that, but you get the gist of it. Now to use tools, we just add it here. Everything so far has just been a one line addition. You have your model, you have your system prompt, and then you have your tools. Actually, one second. I just realized I never got rid of our dramatic system prompt, goodbye, Victorian child. Alright. So let's have our normal agent again. Here is a... How we're invoking our agent, and this is, again, just like a fake journal entry that I've put in. Today, I finally shipped the feature I've been stuck on for a week. The bug is a caching issue, etcetera, etcetera. So, again, we have our human message, our input. And look. Under tool calls, which previously we saw, right file, etcetera, it's called our mood tag tool. And it's a very neutral response. So, apparently, it's a mix of emotions rather than a single clear one. There's some relief and satisfaction. You know, finally shipped. Feels good to have it done. There's some lingering unease. A little worried about whether the fix will hold up, and we have a score of 0.49. So this is just one example of a tool. Again, you could use this however you want. Truly, the sky is your limit. It just has to be a function that you can call, and that's it. Alright. Now we're going to delve into memory, which the way we see it with DeepAgents, it's sort of categorized into short term and long term memories. Long term memory is about what persists across conversations, but short term memory, think of it as just one conversation and what's happening there. So we'll look into short term memory here. Short term memory for any agent built with Linkchain is managed using a check pointer. It's what lets an agent remember earlier turns in the same conversation and it's tracked by something called a thread ID. Now to use this, we have to import the check pointer. So right here, import in memory saver. Now down here is where the thread ID magic works. So thread ID of one. It works exactly the way an identification system works. If I were to change this to two or three or a, b, c, whatever, anything but one, it's almost like starting a brand new conversation that has nothing to do with thread one. So it's all maintained by its by its own thing. If you want to make sure that your agent knows what you're still talking about and maintain this history, you have to keep the same thread ID. So in order to use this, you just add your check pointer in, again, a one line addition, and then you invoke it. Okay. Here's my message to the agent. Hello. My name is Jess. Today, I feel elated because my project was launched. And then, again, we invoke the agent, but we also have to add this config so that it knows we're using the same thread ID of one. And now... Yeah. So this is what I said to my model and my agent, and it responded. Hi, Jess. Congrats on launching your first project. That's great news. But the real test comes with whether or not it remembers me. So here, we're sending a follow-up message. What's my name, and how do I feel? What's my name, and how do I feel? It remembered me. You're feeling elated today. Thanks, Claude. However, if we were to change this, it worked previously because the check pointer essentially replayed the earlier turn back into context because they shared a threat ID. But if they don't share a threat ID... Let's change that right now. It's gonna forget me. That's very sad. I thought we had something. But it no longer has any access to information about me. So that's the importance of making sure you maintain a threat ID if you do actually want this to remember. And we'll look into that a little more because that feeds into human in the loop. This... Again, it was the very first thing that I brought up about how if you have financial transactions or... And let's say you're sending a very risky external email, something that you basically wanna double check before it actually goes out, that's what human in the loop is for. And it works by interrupting the agent loop. So interrupt on pauses the agent mid run so that you can approve, edit, or reject the specific tool before it executes. And then... So it pauses. You do your thing. You give your input, and then it resumes again by invoking the agent with this specific line. And in decisions, you put your type in. So you could approve, edit, reject. You add that here. So here I've written another tool. It's called share journal entry. So this supposedly shares my journal entry, which I don't know why anyone would wanna do that. Not trying to put my deepest, darkest secrets out there. But, again, that's why you wanna be careful. It shares a journal entry to an external platform. This doesn't actually do it. It just simulates the send, but it works the same way. And, again, to use this tool, I just add it to my tools list, which is here. And then I also add my check pointer, again, very important, and here, interrupt on. So the check pointer essentially saves the agent state at the interrupt point so that it can be resumed later with my decision because it's going to interrupt when this tool is assigned true. So when they see this tool, it's gonna stop, ask for my permission, and then continue. And... Yes. And here's my thread ID. I'm using text instead of a number this time, but you wanna make sure to keep this the same. Because if you don't, it's kind of like starting a brand new conversation after pausing halfway through, and it's not gonna know what's going on. So keeping the configuration the same, here's my message. Start a journal markdown file. Log a new dated entry. I'm going to set up human in the loop approval today. Will be good to have a real gate before anything gets shared externally. It'll read the fallback to me and then share the most recent entry to this fictional team stand up platform. And then here, we invoke our agent, like I mentioned earlier, with the same threat ID. And here's where human in the loop works. If there's an interrupt, which it will because of the tool, it'll pause. Right here. It pause for approval. Now if I wanna approve, all I have to do is accept here. Oh, what is going on? I have to put approve. No? Oh, I have to run this again. I see. I see. Alright. So... Oh, the reason there's so much text is the model just likes to talk. Alright. So now that I've approved it, it goes ahead. Here's my message. It wrote the file. I'm going to set up human in the loop approval today. Would be a good tab, Realgate before anything gets shared externally. It read the file back to me, which I asked it to. There's four lines in this journal. And... Yeah. So it worked. However, let's say I wanted to reject it. I have to run this code again because in order for human in the loop to work, we have to go back to the point where it stops and asks again. So running this block of code basically resets us back to whole stopping and waiting for the human decision. So now it's waiting for me. What's my decision? Reject. And let's see that. Great. Again, my human message, my input, it's writing the file, which we saw earlier, and it's reading the file. However, user rejected the tool call for shared journal entry with ID. The tool was not executed. This is the tool message, so this is what's literally happening behind the scenes with the tool call. Do not retry this tool call unless the user explicitly requests it. And then here's our plain language summary, which is what you would normally get, just the very end. Looks like the share action was rejected. I won't retry it. So that's human in the loop, and that's how it works. So very important for things like, again, financial transactions, anything that needs to be reviewed again. You can gate it for any tool call. And now sub agents, which we did bring up earlier. These are basically the mini assistants, and they... And you can hand specialized work to sub agents because they have their own system prompt, their own toolset, and their own context window. So the way it works is you have a name, a description, and their own system prompt. Very similar to other tools, it works the exact same way. This is how the model knows... How the agent knows when to call it, same thing with the description. And then with the system prompt, you can get specific with it. You are a life planner. Read journal.md in full, etcetera, etcetera. I could add in here to speak like a pirate and this sub agent will, but not necessary because their whole purpose is to send results back to the main agent. And here I have two sub agents, the first of which is a life planner. So this is going to look at all of my journal entries and turn any repeated complaints into a weekly plan of action. And then devil's advocate, which surfaces the practical downsides of a decision, will help me evaluate whether or not something is a good idea. So here are our two sub agents. And the thing is you will always have a general purpose sub agent. And it usually works great, but if you wanna get really niche with it and have specific instructions, it's best to write your own like I did earlier. So this chunk of code just basically make sure that it doesn't call the general purpose subagent and it calls mine. And it works the same way. It's a one line addition to create deep agent. We have our life planner subagent here and the devil's advocate subagent. Alright. Here are some fake entries that I've put in. The journal has been seeded, and now we invoke it. So I'm going to ask my agent this question or more of a statement. I'm so overwhelmed with everything I need to do. Can you help me get organized? Now I haven't asked for a specific sub agent here, but the model is going to call for it because I added a line earlier with my sub agent. If the user mentions anything about being overwhelmed, call the life planner sub agent so it knows to call that specialist. Alrighty. So here is my entries. I'm exhausted. Another retiring day. Feeling overwhelmed. Wow. I'm really going through it in these entries. My job is going fully remote. I'm still tired. Yeah. Etcetera. So a bit of a rough week, but not to fear because sub agent is here. It calls write file, so it's writing the files. And then I've logged all five journal entries to journal.md, which is what I asked it to do. And finally, here. This is what we asked. I'm so overwhelmed. Can you help me get organized? It calls the task tool, and here's our sub agent, life planner. Alright. Here's the weekly plan based on your journal. You've mentioned being tired on three separate days. Laundry is your most repeated chore, showing up three times with, oh, with zero progress. Okay. Gotta do my laundry. But... Yeah. So it's listing out all the things. It's saved to a markdown fire... File called planner dot m d, and it's come up with a personalized weekly plan. So since laundry keeps resurfacing without ever getting done, take it off your plate entirely. A wash and fold pickup service. That's just one example. And it saved all of these plans, how to make my day better, plan for remote work transition, and etcetera. Now the main agent does not need to scrape through and look for all of this information. It's too much for it to deal with. It's dealing with the bigger issue of maintaining my journal. This is what a subagent is for. And now if I wanna ask another question, should I get a cat? This is where our devil's advocate subagent is really useful because it'll specialize in manic questions like this and take a look. So, again... Oh, this is back from the beginning, all of our journal entries. So overwhelmed. Alright. Now should I get a cat? It calls our subagent devil's advocate. I didn't tell the model to do any of this. It chose to do it. So you're weighing getting a cat now that your job's going remote. Here's the unglamorous side, including some stuff your own entries are kind of waving a flag about. You're already behind on self maintenance. Damn. Okay. Money, vet bills are unpredictable, but you get the gist. So it's helping me organize all of these things and keeping so much unnecessary context out of the model's main context window because I'm not always asking whether or not I need a cat. I'm not always asking about some bigger life decisions. That's the subagent's job, not the main agent. But... Yeah. So to wrap up, we built a file system backed agent with a way to swap personas, a custom tool with sentiment analysis, short term memory across turns, a human in the loop approval flow, and two sub agents that the main agent picks between on its own, one of which writes an explicit visible plan instead of leaving it in an implicit chat reply. So there's actually more that's covered in a Langchain DeepAgents Academy course, but let me navigate back to my slides and show you that. Let's take a look. Yes. So here is a take home practice for you. Please make a copy of this. Actually, let me, hold on. Let me share that again. Okay. Yes. Giselle should be sending a link right now in the chat. But if not, I believe if you navigate over to the docs tab, you will see that. Please make a copy of this notebook instead of requesting to access to edit it directly because, otherwise, it would edit it for everyone. So please make a copy. Feel free to scan these QR codes. But, again, the link is being sent. That might be easier. If you cannot access the Google Colab for whatever reason, here's the GitHub repo, so feel free to play around with that. And for context, this notebook is similar to what you just saw me go through, but with many more customizable aspects. So you can actually build whatever deep agent you want. You don't have to stick with my journal agent. I've added some fun tool options for you to play around with. So you could build a stock tracker agent if you want or a Pokemon agent. I've added a couple fun things in there. The sky is your limit. Feel free to make your own tools too. It's very easy, and you have many options. Yes. I'll leave this on the screen for, like, another couple seconds. And then... Yes. The links are in the chat, so feel free to refer to that. And, finally, if you wish to learn more, we do have a free online self paced course on deep agents. It's online Chain Academy. It goes into a lot of detail. We've just brushed the surface with sub agents. There's asynchronous sub agents and so much more. Stopped by a really cool instructor. And if you prefer a live instructor like today, though, I actually am doing a workshop on context engineering. So that was basically all the stuff with, with, like, summarization and offloading and more, especially to do with long running agents. I'm doing a workshop on that on November 3. These are the links for it on the right. But, again, I think Giselle is sending everything in the chat. And then we also have another workshop coming up by my fellow education engineer, Divya, and it's about agent evals. And it's on the twenty eighth, so it's next week, Wednesday or Thursday, depending on your time zone. And... Yeah. So I really hope we'll see you there and join. This was a lot of fun for me. Hopefully, it was a lot of fun for you. And I will stop screen sharing now because I believe it's probably easier for you to access the links. But, yeah, hopefully, we've managed to get around to most of your questions in the q and a section. But, again, feel free to check out LinkedIn Academy. Truly, I'm updating it all the time. We have a lot of different resources. There's quizzes. There's homework assignments. There's videos and text, so many different kinds of media, homework, all the different ways you wanna test your brain and try to figure out if you, wanna learn more about a specific topic or if you feel like feel like you know it all. So, yeah, thank you so much for joining. I will hand it back to Giselle. And, oh, these are some really funny poll, questions. Who's picking safely connect a horse to a carriage? I hope I hope people pick that because that's technically correct. Very true. Very true. then one last thing is that I'll be launching a survey now, because we definitely wanna get some feedback as to which topics you wanna see from us in the future and then, just kind of get some feedback on Jess and this session in general. So welcome any thoughts, questions, concerns, anything really. And feel free to join us in in the future for our future workshops. Again, all the links that... And things we talked about are linked in the docs tab that is next to the chat and the poll and the q q and a on your screen. So please feel free to take a look there. And then as a reminder, yes, the session is recorded, and you will get access to the slides and the recording afterwards. Thank you again so much for joining us.