How we eliminated Sales Admin for a team with Ai (real case study)

Rory Ridgers built an AI copilot that eliminated admin work for a sales team drowning in scattered data across HubSpot, Slack, Gmail, and seven other tools. A multi-agent system accessed through ChatGPT handles everything from gathering context to executing tasks across all platforms. The team went from losing hours daily to repetitive work to asking natural-language questions and getting prioritized task lists and automated actions.
Chapters
What's up guys? In this video, I'm gonna be walking you through a real system that we built for a sales team that automates a massive chunk of their admin work. I'm going to briefly run you through the client's main issue that they had, and then the solution that we proposed, and then also an insight into how that implementation actually looked. And then what I'm gonna do is I'm gonna take you inside of NAN and I'm gonna show you what we actually built for them and the results. Just quickly, if you dunno who I am, my name's Rory Ridgers and I run an agency called Autonomously AI where we help US and UK business owners find and eliminate their operational bottlenecks in just 14 days to help business owners be more focused working on the business, rather than in the business. So if that sounds like something you might be interested in, I'll leave a link to my website in the description and you can go ahead and book up a free discovery call. But without further ado, let's jump into the video. Okay, so first things first, I quickly just want to run you through the client's main issues. So the client came to us, they're a fulfillment company, and they saw that their sales team was spending too long on the day-to-day sales admin. Just simple things like finding information, checking on tasks, updating the CRM, going through meeting notes, sending out quotes and prices, All of these little things, they're small tasks that quickly add up and translate into actually a few hours a day. So a very simple, very common issue, basically just their sales team were spending too much time not actually selling and just doing admin things like messing around in the CRM, looking for messages through WhatsApp chats, trying to find the right email address for this person so they can email them over a price, all of that kind of stuff. The kind of things that a salesperson shouldn't actually be doing, the kind of thing that a salesperson shouldn't actually be doing because it's not really the best use of their time. So the solution, the solution was to create a unified a unified interface where all data sources can be interacted with. The data sources include things like HubSpot, Slack, Google Drive, Google Calendar, Gmail, Fireflies, and WhatsApp. Those were the main platforms that they were using. This way, the sales team can easily retrieve data from multiple different sources and perform tasks across all of these platforms without ever having to leave the interface. So essentially, rather than having to have all of these different data sources open, like HubSpot, Gmail, Google Drive, Google Calendar, WhatsApp, they can just have one interface where they can basically control everything, see what tasks they have to do, get any type of information at any point, update things in the CRM, send WhatsApp messages, everything like that, all in one unified interface. So now let's look at the actual implementation of this. Basically, how are we actually going to do this? We have the issue, now we have the solution, how we're going to solve this. How are we actually going to do this? So the first step was establishing the different data sources and then coming up with the interface/dashboard in which they would be interacted with. So we already have those data sources, as I showed you here. These were the main data sources that we were looking that. And now we had to figure out how are they actually going to interact with this. So in the end, integrating the system directly with ChatGPT became the best option for 3 main reasons. The first reason is building an interface from scratch is a longer and more expensive process. Second reason, the sales team uses ChatGPT every day on their laptops and on their phones, so it makes sense to integrate directly into that rather than to create a custom interface they have to go to every day. And then the third reason, we can use ChatGPT's existing infrastructure to our advantage. For example, the data analysis features, the web search, image generation memory features. So originally, the first thing that jumped out at us, the first idea that we had, was just to build a custom interface or dashboard. And that would be good for some reason. There's lots of pros of doing that. Of course, you have full control over everything that's displayed and how it all looks and how it all works. But the main issue is, um, the sales team, basically they just don't want to go to a custom interface, right? They already have all of these different data sources. And the reason that we're talking to them in the first place, because they have all these data sources everywhere and all the information is scattered in different places. And they constantly have a bunch of different tabs open trying to find information and just trying to do these day-to-day tasks. So then by creating another custom interface and another website for them to go to, it's just adding to that even more. It's just saying, hey, you've got all these different data sources everywhere, all these tabs open, here's another tab that's now going to solve that issue. It doesn't really make sense. We want to integrate directly with something that they already use, so it's just seamless for them. They don't have to have another data source or like another thing that they have to have open. And also, they all have the app on their phone, they all use ChatGPT every day, as I'm a lot of you do that are watching this. I know I always have the tab open and I have the app on my phone, which means they can basically use it from anywhere. And that also ties into the point of it being longer and more expensive for the client to create a custom interface dashboard. So we're more than happy to create the custom interface, but of course it's just a longer process, there's more development work, so it's just going to take longer and be more expensive for the client. And also ChatGPT has this existing infrastructure like their memory features, the image generation, the code generation and, you know, the rendering of the code, the data analysis, all of this kind of stuff is already built into ChatGPT, so we might as well use that. So that was settled. We were going to build the system inside of NAN, and then the actual interface, or the way that the sales team is going to be interacting with it, is through ChatGPT for those various reasons. Next was the context. We wanted the system to be like a personal copilot for the company that knew everything about them. Specifically, it would need to know exactly how the sales team uses each different platform at all. This would massively save time when it comes to the system finding information and performing tasks. Because basically, when they're talking through ChatGPT to the system, if you just want to do a really quick common task that, let's say, they do every single day, like grab these prices and just update the CRM with that information— if the system doesn't know where those prices are and doesn't know how this process usually goes, this will turn into a really long drawn-out process when you're talking to it through ChatGPT. So in the end, it probably would have made just more sense for the salesperson just go do it themselves. It would have been quicker. But if the system has full context, so if you just say something like, grab those prices for this and update the CRM, and it just instantly knows where those prices are, how to grab them, and then exactly where to put them in the CRM, now it actually becomes a time saver. If it didn't have the context, it would've still been able to do it and it would've been sort of cool and maybe slightly convenient. But like I said, it probably would've taken longer than actually manually doing it yourself. But with all the context, it is now actually a time saver. So it's not just like a gimmicky tool. It is now actually useful and saving you time. That's the difference. So to do this, we built a RAG system using Supabase in order to retrieve all of the relevant context. We split into 5 different vector stores inside the Supabase that are used at different points throughout the system. The 5 different vector stores are tool selection that contain general information on how all the software is used and where all the information lies in each of them. CRM with detailed information on how the CRM is used. Business is just general information on the business. People is just general information on other members of the sales team and other members of staff at the company, and also some of their big clients. And then Playbooks is just specific processes, day-to-day operations, and also tips and tricks on how to use certain things and get certain data. So this went through a lot of iterations, but we found that this was kind of the most optimal vector store structure for us to use. If you're wondering why tool selection and CRM are two different things, even though they are sort of just all data sources, the CRM was by far the thing that their sales team was spending the most time in. And there was like, it was way more in the CRM. There's so many different things to it, you know. There's activities, there's tasks, there's contacts, there's companies, there's loads and loads of different things inside of the CRM. Whereas the other tools were just like, WhatsApp is just for messaging, Gmail is just for emailing, uh, the Fireflies was just for looking at meeting notes. There wasn't as much to the other tools, so that's why we made an entirely different vector store just for the HubSpot CRM, um, because they're in it way more. There's way more data in there, there's way more processes and day-to-day things that they do in there. So that is an overview basically of their issue, our solution, and then how we plan to actually implement this. It was split into two systems. It was the backend system in NAN that is going to be actually like retrieving all of this information and performing the different tasks in these different platforms, and then also the RAG system that's going to be collecting all of the business context. So we're going to hop over to NAN and I'll show you inside the systems. So this is the main backend system. This is going to be this part of the system here that's able to retrieve information from these data sources and also, uh, perform actions and tasks inside of these different platforms. So let's just have a quick breakdown of what is actually going on here. So for testing, there was an on chat message received and also the webhook. The webhook is how it is interacting with ChatGPT. So ChatGPT is linked up to this via a webhook. Then on chat message received is just for testing so that I could use it inside of the NAN canvas. So those are the triggers, very, very simple. Then what we have is a Creator Plan agent. So as you can see here, there are a lot— these are different agents here. So this is a multi-agent system, and these are just calling upon different agents. You can see here there are quite a lot of different agents, and there are also 3 vector stores. So essentially, we had the issue of when an input comes in to do something in one of these platforms or tools, or just to do some kind of task, like using the example earlier, grab that price from this spreadsheet and update the CRM and then maybe email this person with it. There's a couple of different things that it needs to do that. And we found that trying to get— if we just had one agent here and we were trying to get that to first get all of the context from the right vector stores and then also call all of the right agents and pass that data in between all the right agents correctly, it was just kind of malfunctioning. It wasn't able to do it because there was way too much context and way too many things for it to remember. So what we did at the beginning is we used a Create a Plan agent, and this essentially will just take the input and then it will use the vector stores to get the different kind of context that it needs. And then it will create a step-by-step plan. It has full context on all of these multi-agents down here. It'll create a step-by-step plan on exactly what this tool caller agent should actually be doing every single time. We found that it performed way better when we did it that way. So let's look inside of this Create a Plan agent and we'll have a look at the prompt. So the prompt is fairly long for both of these agents, but I want to quickly sort of summarize it. What's going on here. So we're saying your job is to create plans for another agent on what tools to use. You have access to 3 vector stores to help you gather context for your plan, and then a little information on how to actually use those vector stores. So don't just dump the query you get into the vector stores. For example, if you say, so what should I focus on today? Don't just input that into the tool. Instead, use it multiple times to get info like my morning routine or typical sales day, etc. So we do break down a little bit later on on how to actually use the vector stores. We've said your vector store tools, it has business to query this for general information and business context. People, input a person's name and get context on them. Playbooks, these are common practices and processes, so query them with how common processes are done and the procedures. Essentially what we've done from there is we've given it all of the tools that this tool caller agent has, the tools being just the other agents in the system. So if we have a look at this, we've just given it a quick breakdown. The HubSpot MCP agent, Gmail MCP, Google Calendar MCP, Google Drive MCP, Apollo company enrichment, Apollo contact enrichment, Fireflies, WhatsApp, and Slack. And then we've given it a breakdown on, of course, what the agent can actually do and how to use it as well. So we've just given it full context on basically all of these tools down here. And then at the bottom of this prompt, if we scroll down, output the plan as well as the names of the tools that need to be performed. And then just a few little extra things, and this is mainly just through testing you add an extra section, and then when sort of like little issues come up and things like that, you can just put them in this extra section. So for example, we gave it the time by using this expression here. So that's just when a user inputs something like, what should I be doing next week, or did this person email me yesterday, something like that, has the time so it knows a reference point for that. So that is basically the prompt for the Create a Plan agent, and it's going to first use each of these vector stores to get the relevant context and then it is going to look at all of the tools that the ToolCaller agent has and output a full plan. So then we move on to the ToolCaller agent. So it's going to receive this full plan from the Create a Plan agent. Then we have the ToolCaller agent, which has a very, very similar prompt to the other one. We break down all of the tools in here, and then we essentially just say to it, you are gonna receive a plan. Here are the tools you have, follow the plan. We try and give it not as little context as possible, but we basically just don't try to overload it with all of this context on like, what exactly it's doing, its, you know, its goals, what it's trying to achieve, all of that kind of stuff. We basically just treat it as a little bit of a robot and just say, you have this plan, it's a very detailed plan, you have these tools, execute the plan, is essentially what we say. Because there's a great emphasis on making this Create a Plan agent make very, very good plans. That's kind of how the whole system works, is around this Create a Plan agent. And then if we just have a look at some of the agents down here, they're all very, very similar. Apart from the HubSpot one and the Apollo enrichment one. So we'll look into one of these. So this here is the Gmail agent, and you can see the inputs just to begin with— or the triggers, sorry— kind of the similar thing to the main agent system. We just have a when executed by another workflow, which is of course this workflow up here. That's what these nodes are. It's called another workflow. So when executed by another workflow, and then also just on chat message received. And it's like that for each of the sub-agents. So I can test them individually. I can just open the chat window like this and test them out each individually. And then it just has a bunch of different Gmail tools down here that allows it to perform pretty much any task inside of Gmail. And then it also has a vector store where it's linked up to the tool selection vector store. Inside of that tool selection vector store, it will contain a lot of context on how to use Gmail. So it's going to query that vector store every single time it gets any kind of input, and just to give it more context on its task and how we usually use Gmail or how the company would usually use Gmail. And the prompt in here, fairly straightforward. What we usually do for each of these, uh, sub-agents is we kind of have a base prompt that first just of course lists out all of the tools that they have and just like a very, very, uh, basic overview of what they're doing. So you're a Gmail agent, you'll be inputted with a Gmail task and you'll have to, and you'll have to use one or multiple tools to complete the task. And then what we do is while testing, we build on it. So there might be some specific Gmail practices, um, that we want to include in the prompt and it's just annoying to put it in the vector store because there's no point kind of hiding it. Vector stores are made for like a lot of information, but if there's just like a quick little thing like, um, always sign off emails with 'Yours sincerely' and then a name, for example, we just put something like that in the system prompt here. So that is how the sub-agents look. This probably looks fairly familiar to you. These sub-agents aren't too complex. The main complexity of the system is up in the main agent part. But what I did want to show you is the HubSpot system. So inside of the HubSpot sub-agent system, there's a couple different moving parts and there's a couple things that look different. Basically, all of the other sub-agents look the same as that Gmail one apart from this HubSpot, because like I said, HubSpot is a lot, lot bigger and there's a lot more data in there and a lot more different things you can do inside of HubSpot compared to like Gmail where it's pretty much just sending and receiving emails. WhatsApp is just sending WhatsApps. There is a lot of things you can do inside of HubSpot. So we followed a similar kind of structure to the main agent system where you have like a planner and an actual tool caller. We do a similar thing here where we have a planner agent that first is linked up to the Supabase VectorStore contain all the information of the CRM. So you already know the drill, it's just going to get a lot of context on how to use the CRM for this specific task before it does anything. And then what we do is a lot of the time the inputs are going to be asking about like a specific contact or a specific company or a specific group of companies or contacts to update them, delete them, change them, add them, that kind of thing. So we found that the best thing to do for this Planner agent is it's linked up to 3 tools here that are linked up to HubSpot. They're HTTP requests, but they're linked up to HubSpot. And what they do is they just get the different properties for contacts, companies, and deals. This way, when we want to update, delete, create a contact, company, or deal, we already have all of the different properties, so we know what data we should be putting in there. Because we found that it was doing a lot of requests to HubSpot with the wrong, uh, properties in there. There's hundreds of different properties for each of them. We found that sometimes it was like misformatting or doing the name of the property wrong, you know, like without a capital letter or with one or with an underscore or without one, that kind of thing. So we made it so at the beginning, if it needs to, it can get all of the contact properties, company properties, and deal properties and send that off to this agent to actually execute the task. That way it fails a lot, lot less and basically just knows what data it's actually putting into the CRM. And then this agent here, this is actually really cool. I really like what we did here. We wanted a HubSpot MCP server because there's so many different kind of things and actions you you do in HubSpot. I think there's about 400 or 500 different endpoints or something like that, and there's not that many tools in NAN. So basically you can't do everything in HubSpot, um, through NAN, just like the native HubSpot integration. So we needed some kind of MCP feature where it just has access to all the different tools. And at the time of building this, there were HubSpot MCPs. HubSpot MCPs were a thing, but they were mainly the kind of thing that you use through, um, Cursor or Claude, that kind of thing. It's a lot easier to set up With this there, you can set it up in an AM, but it is a little bit of a tricky process, and you would have to be sort of self-hosting the MCP and stuff. And because I'm building it— me and my team are building it on here— and then we're having to send that over to our point of contact into the company so he can try it out, and then to the whole sales team, it just didn't seem very, very feasible for everyone to be self-hosting the MCP. Um, so we didn't do it that way. Instead, what we did is a very, very simple workaround, and I actually recommend implementing this into your systems if you want a free, easy-to-use MCP. Essentially what we have here is a Google Doc, and I'll open this up and show you. And this contains all of the different functions inside of the HubSpot MCP. So when, um, an AI agent, let's say using Claude, was to actually use the HubSpot MCP and it was to first ask to list all the tools that it can use before executing them, this would be the exact list that it would actually retrieve. So it's just the name of the function and then basically what that function does. So what we do is we link that up to this AI agent and say, first, before anything, retrieve all of the tools that you can use. And then we essentially taught it how to decode that into a HTTP request. So what it would do is it will basically pick the tool that it wants to use, and then it will know how to generate an endpoint. The body— it already has the credentials in here and already has the headers in here, so it's able to actually formulate the body and the endpoint and the method just from that list. And we have essentially just simulated a HubSpot MCP using just a Google Doc and an HTTP request. So it's free and it rarely, rarely ever fails, especially for like the 99% of just the simple tasks. And it literally never fails. At the beginning, of course, it failed a little bit, but then we have to do prompting and we have to teach the AI agent better how to use it. And now it literally never fails. It's absolutely fantastic. And a great workaround if you want to easily implement an MCP-like system into your NAN systems. Okay, so that is the main system. Now I want to show you inside of this vectorizing system, and this is essentially just what puts the information from the Google Drive into the Supabase vector store. So just to show you inside of Supabase, this is how it looks. We have Business, CRM, People, Playbooks, and Tool Selection. These are the different vector stores. So If we come back over to N8N, this might look really, really confusing, by the way, but it's not. I promise you, all it is is this is the actual system and it's just been repeated 5 times. That's all it is. So essentially, at the beginning here, we just have Google Drive, uh, triggers because there's 5 different folders inside of Google Drive that we're watching out for. Of course, there's 5 different tables inside of N8N because there's 5 different tables inside of Supabase. Essentially what we've done is we've just mirrored Google Drive into Superbase. So in Google Drive, there's just 5 folders with, um, business, CRM, people, playbooks, and tool selection. And then now that is what is in Superbase. So we've just mirrored it from Google Drive. So at the beginning here, we just have a trigger set up for each Google Drive folder when a new file is created, or for when a file is updated or changed. That is all we're watching out for. And essentially what happens is, let's say one of these folders, uh, a new file is added. The reason we've duplicated this 5 times I'll show you how it all works, but the reason we've duplicated it 5 times is just so that basically if one file in one folder gets updated, we don't want to have to kind of like redo the entire system and like make it run through and update the entire system. We want it to just update that one vector store rather than just all the information we have in Supabase. So that's why it's split off into 5 different ways here. So let's say the first one up here, a new file is created or updated, it will come down here and it will shoot up to this one. It just deletes the information in there because I found this is the easiest way. You can have it so it like finds the information in Supabase and updates it and like removes the bits that aren't there anymore, but it's like, it's just a bit of a hassle to be honest, and it's not very efficient. If like you, you're changing the content from a Google Doc, you don't want to have to like then make a system that can go into Supabase, find what's changed, what's different, remove those chunks, and then update it. It's much easier because there's an because there isn't a crazy, crazy amount of data in there, it makes more sense to just basically delete everything that's in that particular vector store and just re-upload it again, because it takes around 30 seconds for that to happen. So it's not a long process at all. Actually, what we do is we just delete the information from this one particular vector store, and then we will just see what has been updated, and then we'll identify if that is either a Google Sheet, Google Doc, or PDF, and just go through the motion of extracting information from each one. So if it's a Google Doc, we just do a simple GET request, get that Google Doc, and we get the content back, and then we send that to Supabase. If it is a sheet, we first have to do an HTTP request to just get all of the names of the sheet inside of that spreadsheet. So you can have like multiple, you know, tabs at the bottom, different sheets inside of one spreadsheet. We get all of them, and then we just get the rows from each of them, and then we format that correctly and send over to Supabase. And if it's a PDF, we quickly download it get the binary, extract the data from that binary, and then again format it, send it to Supabase. And we just repeat that 5 different times here, as you can see, for the 5 different folders inside of Google Drive. And then what we do is we just link that all up to a custom GPT. So this other custom GPT looks— we've given it a name, a description, a prompt, which basically just tells it, um, all the different tools that it can use and basically how to send data over to NAN. So of course it's not actually using the tools, it's just sending the data over to that system in NAN and then displaying the results to us. And if you want to know how you actually set up a tool, uh, connect it to a custom GPT— so if you want to connect NAN to a custom GPT, all you do is— let's go back over to NAN. You've put a webhook down inside of NAN, which we have, as you can see. Change the production URL, so we get this URL here. Come back over to ChatGPT. What you first need to do is go over to ChatGPT, like not creating a custom GPT here, just a normal ChatGPT or whichever LLM, you use Gemini Claude, give it that webhook URL and tell it to make you an OpenAI schema for a custom GPT. And what it'll do is it's just going to spit you out something like this. It's just this schema, and you can see here it contains your webhook URL. So all you do is you paste that in, and then you'd get a tool pop-up that looks something like this. So send to any— and the method is POST. Come back over to any— and make sure your method is set to POST. And then this is the path, as you can see. Respond using Respond to Webhook node at the end. So it just means it'll hit this and then it will send back the data that is outputted there. And then for the allowed origins, just do an asterisk, which just means it's going to allow all origins. So it can be a little bit tricky sometimes. Sometimes, um, requests from ChatGPT can get blocked if this isn't turned on. So just make sure you're allowing, um, all origins. It's not going to get blocked by CORS. CORS is just— it's annoying sometimes. It will block, uh, things that seem a little bit suspicious. And then all you need to do as well is just add in a privacy policy here. This privacy policy really doesn't have to be anything fancy. Mine is literally just a simple HTML page that basically just says what the tool does and stuff. Uh, ChatGPT just needs it in there essentially just to tick the box. That's all you really need to put it in there for. So guys, that is the entire system. And now this is a system that they're actually using, uh, their sales team are using to basically get information, do analysis of their information, and also create tasks and perform actions in these different apps, like sending off WhatsApp messages, getting information from one place putting it into another. They're even able to just go to the custom GPT and say to it, what should I be focusing on today? And it will do a full analysis. It knows what they should be doing most days based on all the context from that RAG, uh, vector store. And then it can look at everything, all their outstanding tasks, all of their emails, all of their WhatsApp messages, and give them a full plan on exactly what they should be working on today. And then priority order as well, which is really, really cool. So it's becoming like a real copilot for this sales team.
More from Rory

Dynamic Workflows are crazy. This is how to actually use them (beginner's guide)










