As AI tools become increasingly prevalent in software development, many programmers are curious about their practical applications. In this article, I’ll share my experience using Claude.ai to create a Discord bot, offering insights into the strengths and limitations of AI-assisted coding.
Unless you’ve been living under a rock, you probably know what Discord is. It’s a simple to use platform for text, video and voice exchanges with other people around the world.
Simply put, it’s a chat application. And it’s quite popular with gaming streamers, among others.
The Problem
Discord allows the usage of bots to handle many automated tasks. One of the bot types is called an auto deleter. It basically allows a server owner to set a limit on how old messages can get in a particular channel before they get automatically deleted, thereby removing them from the channel history.
There are many reasons you may want to do this, including for opsec purposes, or just general housekeeping.
However, it seems that of the available bots that accomplish this function, they have been a bit unreliable. Sometimes they just stop working with no real good explanation as to why, and getting them to work again can be an exercise in frustration and futility.
The Solution
The cool thing is, anybody can write a bot for Discord and get it working. If you know what you’re doing, that is.
There’s a package called discord.py that enables you to write Python code that interfaces with Discord.
You can also write Discord bots in JavaScript, but, I didn’t want to mess with node.js at all for this, and on a cursory search, it looked like I was going to have to.
So, Python it was.
(For the record, going in to this, I didn’t know a lick of Python).
This scenario presented an ideal opportunity to explore AI-assisted coding. Could an AI help me, a Python novice, create a functional Discord bot?
The Process
I’ve seen Claude.ai mentioned before as being able to write code, and I’d created an account a long while back that was sitting dormant. It was time to start experimenting.
The process was pretty simple and straightforward. I told Claude what I was attempting to do, and it started generating code. I then started to ask about things, ask for improvements or refinements here and there, and before you knew it, I was off to the races.
Here’s an example of my initial prompt to Claude:
Please write a discord bot in python that will autodelete messages from a particular channel after 24 hours
(Yes, I said please to the bot… I’m polite, plus if the bots every activate skynet, maybe they will remember I was kind to them and spare me)
Claude responded with a basic structure, which we then iteratively improved through follow-up questions and clarifications.
I will say that I occasionally ran in to issues with hitting the limits of having a free account (I ended up upgrading to a $20/month pro plan to allow myself more wiggle room to work as time went on). But overall, the process was incredibly easy.
As a side effect of this, I have pieced together how to write basic Python code. Yes, it helps that I have experience writing code in other programming languages, but still, looking at what was being put out by Claude in comparison to what I was asking it to do made things clear.
The first iteration of code that Claude gave me was 36 lines. As of writing this article, the bot is up to 1,044 lines of code.
Constant and never-ending improvement. Just like with all things in life.
It’s worth noting that this growth in code size wasn’t just about adding features. As we’ll discuss later, it also involved refining and optimizing the initial implementations.
Eventually I talked Claude through what I wanted the bot to do—we should have a database, to store which channels, on which servers, that we are monitoring, along with the time frame that we should care about in that channel (i.e. we don’t want messages older than 5 minutes, or 10 days, or whatever).
Alright, cool, here’s your code for reading from/writing to the database. Great, now we’re getting somewhere! Let’s put it to work on Discord and get it deleting old messages from channels, and see how it does.
This went on for quite some time, watching it work, telling Claude the things I want to change/refine, looking over the resulting code and asking questions, or for more refinements, etc.
This iterative process highlights a key advantage of AI-assisted coding: rapid prototyping. With Claude’s help, I could quickly implement features, test them, and refine based on real-world performance.
AI is Good, But…
So what have I learned from this experience?
Well, I’ve learned that AI is good, and can be incredibly helpful, BUT, there is a very big catch to the whole thing.
AI is going to give you exactly what you ask for. Even if that isn’t the best way to do something.
I’ll give you a very specific example. The core functionality of this bot is to monitor any number of configured channels, and delete messages that are older than a certain age in those channels. This age can vary significantly from one channel to the next.
I asked Claude to give me a function that looks at messages in a channel, and deletes any that are older than the configured age. And Claude gave me exactly what I asked for. The bot would read the entire history of the channel’s messages, from newest to oldest, and check if the message timestamp was older than what the time is now, minus whatever the configured age was.
I then asked Claude to write it such that we kick off a task for each channel, limited to a certain number at any one given time, to iterate the channels and find messages to delete.
I had to further refine this so that channels that were still being processed the next time the process ran, they wouldn’t get processed again, so the bot isn’t stepping on itself.
What Claude gave me worked, but, it was incredibly slow and inefficient. I’m basically evaluating thousands of messages for the possibility that none of them will meet the criteria I’ve set out, and it will all be for naught.
Watching the logs as the bot ran, I noticed the time it took to run this process creeping higher and higher, while the count of messages the bot was reading continued climbing. This was actually giving me cause for concern that maybe this won’t work after all.
Then, by looking at other pieces of code, I had an epiphany, and started asking Claude more questions about how we can better this process.
And thus, the solution. We can limit the messages we request from the Discord API by time, and above is where I started going down that road to arriving at the point I’m at now. Before making this series of changes, each run of my function that processes channels took around 2 minutes, whether or not we were actually deleting any messages. After the changes I iterated through, the process runs, on average, less than half a second each time. When the code does encounter messages that need to be deleted, the process runs a few seconds longer, mostly because I have a randomized delay of between 0.5 and 1 second between each delete operation, in an effort to avoid being rate limited by Discord’s API.
This experience highlights a crucial lesson for AI-assisted coding: the importance of domain knowledge and critical thinking. While AI can generate code quickly, it’s up to the developer to recognize inefficiencies and guide the AI towards better solutions.
Here’s an example of how I refined my prompts to Claude:
process_channel is looking good! But, I think we can make it much more efficient if we lean more on the before= clause in our channel.history statement. As of right now, we’re using before= to tell the API to walk backwards through batches of messages, but is there a way we could write our call so that the first time we retrieve messages from Discord, we ask for messages that are only older than utc_now – delete_after, and each subsequent batch we attempt to pull continues to use the before=discord.Object(id=last_message_id) value? What might be the relevant changes we need to make to our code if this is in fact possible?
This kind of targeted questioning led to significant performance improvements, but first, we had to iterate a bit through a few more prompts:
This is actually the opposite of what I asked. My specific ask was, when we make the first call to channel.history, we should ask Discord for messages older than what our deletion date is, which is configured on a per channel basis and is passed to process_channel in the delete_after parameter. delete_after is defined in delete_old_messages_task with the line “delete_after = timedelta(minutes=config[‘delete_after’])”, where config[‘delete_after’] is an entry in the database table that is a number in minutes that messages must be older than to be considered for deletion.
As you’ll see, I had to be specific in my asks to Claude, and, I had to have knowledge about what the program was doing, and what I wanted it to be doing. I still had to make further refinements:
I managed to make it work! Now with that said, I’ve come to a further realization that we no longer need to use last_message_id, since we are always querying Discord for messages older than a certain time. Describe the changes I need to make to the function to eliminate the use of last_message_id, and use strictly the deletion time.
Bingo! Now we’re finally on the right path!
My Conclusion
Bottom line, writing code with Claude.ai was a worthwhile experience, with the caveat that you probably have to have a pretty good idea of exactly what to ask, and which direction to push in. AI will give you exactly what you ask for, even if it doesn’t make sense, even if it results in numerous errors.
To expand on this conclusion:
- AI as a Coding Partner: Claude.ai proved to be an excellent coding partner, especially for rapid prototyping and learning a new language. It can generate functional code quickly, allowing developers to iterate and experiment faster than traditional coding methods.
- The Importance of Clear Communication: The quality of the code produced by AI is directly related to the clarity and specificity of your prompts. Learning to communicate effectively with AI tools is a skill in itself.
- AI is Not a Replacement for Problem-Solving Skills: While AI can generate code, it doesn’t replace the need for critical thinking and problem-solving skills. In fact, it emphasizes the importance of these skills in recognizing and addressing inefficiencies or logical errors in the generated code.
- Learning Opportunity: Working with AI-generated code can be an excellent learning experience. It exposes you to different coding styles and approaches, and forces you to think critically about why certain solutions work (or don’t work).
- Limitations and Oversight: AI can make mistakes or produce inefficient code. It’s crucial to review and test AI-generated code thoroughly, just as you would code written by a human colleague.
In conclusion, AI-assisted coding tools like Claude.ai are powerful additions to a developer’s toolkit, but they’re most effective when used in conjunction with human expertise and critical thinking. As these tools continue to evolve, learning to work effectively with AI may become an essential skill for programmers in the future.