Language Learning with Robots
Several years ago, I started self-studying Mandarin Chinese. I'm still at an intermediate level, but my previous partner and I communicated primarily in Mandarin. It's unlikely I'd have continued to study this long without the help of software.
I will share how I use code I wrote, tools others created, and AI to make learning language easier. While Mandarin Chinese is my primary language of study, I have automated the study of European languages as well. The methods here are relatively transferable.
Try to have fun with your language learning system! For me, the whole point of setting up this system was to make language learning more enjoyable and less tedious. If any of these sections seem too technical or boring, skip it.
Flash Cards
I've memorized many different things in my life like geography, english definitions, foreign language translations, keyboard shortcuts, and programming concepts. Each time, I used Spaced Repetition Software. Spaced Repetition Software are like flash card apps that help people remember things.
Specifically, the app I've always used is Anki. These days, it helps me remember the meaning of Chinese characters, words, and grammar.
While working with the flash cards for language learning, I noticed that much of the time was spent on looking up information and creating the flash cards instead of actually studying them. I started writing code to automate some of that process and over the years it's evolved into a large monolith of code.
At a high level, there are three main phases in my flash card automation:
- I communicate my intention to my code in how want to change my Anki flash cards.
- On a recurring basis, some code checks to see if there's anything that needs to change... and changes it. The code will sometimes need to query my existing flash cards before making any changes.
- The changes to Anki gets synchronized to my phone and laptop via Anki Web.
Although you may find replicating this system on your own a daunting task, consider that you'll spend thousands (probably tens of thousands) of hours learning a language.
So what is an intent that I might express? A common example is adding a new Chinese word into my Anki flash cards along with its definition and pronunciation. (#1) I use the iOS app Shortcuts to pass the new word into a queue on my computer server on the Internet.
(#2) Some code on that computer server wakes up and notices there's a new word. The new word is slang, so it's not in the Chinese dictionary that I installed on the computer server. The code constructs a text prompt to ask an AI what the definition of the word is. With the definition in hand, it looks up the pronunciation of the Chinese characters of this word and passes all this information to a plugin for Anki called AnkiConnect that adds a new flash card to Anki.
But this new flash card was only created on my computer server. I want to review my new flash card on my phone and laptop. Fortunately, Anki has a free service called Anki Web that synchronizes changes to your flash cards between devices. (#3) So the computer server syncs with Anki Web and then I will see the new flash card the next time I use Anki on my phone or laptop.
#1 Expressing intent with Web App and iOS Shortcuts
Making web apps is a relatively common skill amongst programmers. Vibe coding also makes it possible for even non-technical people to make web apps, so I will discuss making a web app as the main way to express intent to your code. However, if you only use your laptop for studying language, there's no reason you can't just run everything locally on your laptop. You could even run everything as code scripts, without using queues. Keep it simple if you'd like.
I'll assume you're making a web app on a computer server, since that will both make it accessible to multiple devices and also doesn't require your laptop to be on in order for the code to run.
Your web app should take text and store it somewhere for later. The one I made is very simple and ugly 🫣, but it works! I have a dropdown menu that lets me change which kind of intent I want to express (which queue I want to put it in).
When I tap/click “Emit”, this data gets saved in a mandarin.new_phrase queue on my computer server, my queue for adding new Mandarin phrases. You can add as many of these queues as you'd like... one for each of the different kinds of tasks you'd like the computer server to do for you 🤩.
How do you store this data into queues? That's up to you. One file per queue is fine. Queues in RabbitMQ works. A table in SQLite works. I use a PostgreSQL database with a table schema like:
After a couple years using my web app, I noted it was a little clunky on my phone. So I switched to using the iOS Shortcuts app to make icons on my home screen that put things in my queues like my web app:
If you have an iPhone and want to make a shortcut, the important piece is the “Get contents of URL” block, which will send it to your web app. Feel free to start with my example.
Anything you can do to reduce the friction of automating your language learning will make you feel more invested in fixing your system when it breaks and improve it over time.
#2 Regularly execute code to add, change, and remove flash cards
Here, the automation begins. This is when you have code that wakes up every so often (mine is every minute) and checks if there are any new items in the queues. If there are, the code will start working on making changes to your Anki flash cards.
A simple solution for this is to use cron, which is available on most Linux systems and MacOS. I used cron for years, but recently switched to just using schedule in Python because starting my code each time cron ran it took a fair bit of time/resources.
When I was using cron to run the code that checks the queues, I'd run it inside a docker container. For example, if you've installed cron inside a docker container and copied your code in as well, using something like this as the ENTRYPOINT for a docker container will set up cron to run your code every minute:
After your code is running regularly, you'll need a way to interact with Anki. I mentioned that I use the AnkiConnect plugin, which makes it possible to talk to Anki with your code (over the network). To make it more portable for my computer server, I ended up running Anki inside a docker container using Headless Anki, which itself uses AnkiConnect.
With AnkiConnect set up, there is now a way to programmatically change your flash cards. So now, when your code wakes up, it should do something like:
- Check the queues for new items
- If there's something in a queue, use the resources at hand to plan what changes you'll make to Anki e.g. querying Anki with AnkiConnect, looking up words in local dictionary, asking AI (more on these later)
- Use your AnkiConnect setup to create, modify, and remove flash cards as needed
- Remove the items from the queue that you just acted on (or mark them as done)
Translating with AI
Previously, I used the Google Translate API for years to translate Chinese words and sentences to English for my flash cards. But I discovered that using AI chat services both produced better results and allowed for more customization e.g. specifying the source language and target languages as “Taiwanese Mandarin” and “American English”, respectively.
At the time of writing, here is the prompt I prepend to every translation request to the ChatGPT API:
You are a translation bot. You will receive a JSON input list of strings in one language and must translate them to another language. For example, if you got this input: { "from_language": "Taiwan Mandarin", "to_language": "American English", "phrases": [ "我是美國人。", "你的媽媽生病了嗎?" ] } you should respond with a JSON translation like this: { "translations": [ "I am American.", "Did your mother get sick?" ] }
Linguee
If you're learning a language supported by Linguee like German, French, Spanish, or Portuguese, then you can also use their dictionary for translating specific words. The entries from Linguee often include things like part of speech, example sentences, and even audio pronunciation files!
Linguee seems to throttle even a modest number of requests to their unofficial API that you'd otherwise be able to complete using their phone or web app. To overcome this limitation, I set up a docker image that regularly changes which IP it makes the request from using TOR:
If you want to use the audio pronunciation files, don't forget you'll need to download them into your Anki data directory somehow.
English Dictionaries
You can improve your understanding of your native language too! I have a queue for English word I come across that I don't know. The code that reads this queue first checks the Wiktionary API for the word's definition.
If the word is not present there, it uses Urban Dictionary's unofficial API (use https://api.urbandictionary.com/v0/define?term=myword), since more often than not the word is some modern slang. Sorting the results by thumbs up / (thumbs up + thumbs down) (credit Evan Miller) will generally yield better results than just taking the first one.
#3 Sync with Anki
Now, you just have to append one last step in your code: synchronizing with Anki Web. AnkiConnect has a sync feature which should work fine.
If you are making changes to existing cards, you may want to synchronize with Anki Web before making the changes, as modifying the same flash card on two different devices usually only ends up getting one of the changes.
Code that runs on its own
Technically, your code doesn't need to wait for input from you; you could just have it do something on a regular basis e.g. every hour, every day. In the past, I've had code that...
- Replaces common abbreviations and acronyms in my Anki flash cards with their full version
- Gets an AI to email me little stories in Chinese using the flash cards I need to review that day (more below)
- Compresses large images I put on my flash cards into smaller images to save space
- Checks if I've learned new Chinese characters and sends a text message congratulating me on my progress
One-Off Scripts
Occasionally, there are changes you'll want to make to Anki, but only once or at least not regularly. I have a Jupyter Notebook where I write code to perform these one-off roles. Creating a queue for each of these would work too. Writing the code for each in a separate file would work as well.
The scripts include things like:
- Introduce n new Chinese characters for me to learn, along with new words that I can now read because I now know these n Chinese characters
- Add pronunciation audio files to all my Portuguese flash cards
- Tell me which Chinese characters are in this podcast transcript I pasted are characters I haven't learned yet?
- Ensure that each flash card with Chinese words/sentences has the characters for both the simplified and traditional character set
- Declaring Bankruptcy: Reviewing flash cards is sometimes a hard habit to keep. Reviewing them can be like a psychological game. Therefore, if it's been too long since I reviewed all my cards, I will sometimes use code to go through all flash cards I have to review and mark them as reviewed. I'm lying to myself, but seeing the number of cards due go from thousands to none is really good for long term morale. I'd rather encounter those flash cards in the future and get them wrong and have to re-learn them than give up reviewing altogether.
- Ask AI to add an etymology explanation to each Chinese word so it's easier for me to remember, regardless of whether it's 100% correct (more below)
- Calculate how close I am to knowing all the Chinese characters and words in the next level based on China's proficiency standard (HSK)
- Insert many new flash cards based on a dataset I found online (i.e. perform an ETL job)
iOS Text Replacement
Sometimes when I need to quickly look something up in Anki or make a quick change to a flash card, there are search terms that are a bit tedious to write. iPhone has a feature called Text Replacement that lets you expand a short string of characters into a longer one (I've heard Android has a similiar feature under the keyboard settings):
Text Replacement in iOS makes searching Anki much easier
You have to first go to the Settings and add entries into Text Replacement:
Using AI
There are huge benefits to using AI for language learning besides generating flash cards. Sometimes the AI will make mistakes e.g. wrong explanation for grammar, insist that certain phrases are formal or common when they're not, answer “Correct” to your question when it's... not correct. But in general, the recent AI models make mistakes on simple things like this infrequently enough that they're tremendously worth using.
Listening and Reading Practice with Notes
My good friend JCo taught me this technique for practicing both listening and reading in one's language of study:
- Listen to the audio recording for the foreign language text without first reading it
- Read the text at your own pace. Look up words you don't know
- Read the text along with the audio recording, optionally speaking it aloud at the same time (Shadowing)
- Listen to the audio recording again, skipping backwards a few seconds as needed when you don't understand a phrase
I use this technique all the time! It's amazing how my listening comprehension goes from ~30% to 100% on the same passage so quickly. With AI, there is more you can do with audio recordings. Here is what I do now:
- Save a podcast or textbook audio recording to my laptop
- Use an AI online service or a Google Colab notebook to transcribe the audio
- Pass the full transcription to an AI and ask it to restructure it into small paragraph chunks
- Use JCo's technique above, but while reading the text, ask AI questions when you're unsure of grammar points or meaning. If using a notes app like Tana, this will also create connections between all your Q&A with the AI and the original text in your notes

Asking questions to AI about the foreign language text while reading it Tana
For transcribing the audio in step #2 just above, the Google Colab notebook boils down to something like:
Writing Practice with Prompts
I think learning to write in a foreign language is done best with very quick feedback. To that end, I have an AI prompt that allows me to get feedback on messages I'm about to write to my Mandarin-speaking friends. Here's what the usage looks like:
With these interactions, I believe the AI occassionally makes mistakes; however, the alternative is that nobody, not even a computer program, reviews my text nor gives feedback. Getting feedback from an AI that occasionally makes mistakes is a good tradeoff to me.
The prompt (below) is not terribly complicated. I adjust it whenever I notice that there's a pattern in the output that's wasting time or making it more tedious or inaccurate.
The user is a native English speaker learning Mandarin, translating from English to Taiwanese Mandarin Chinese as practice. They will first write the text in English they want to translate, then their attempt at a Chinese translation.Please point out what could be better, prioritizing Taiwanese Mandarin phrasing and words. If there is another simple construction that (Taiwanese) Mandarin speakers say instead, state that as well. If there are English words in the Mandarin, leave them as English unless asked otherwise. Do not be supportive. Be as straightforward as possible. Don't worry about formalities. Avoid introductions, conclusion, outline, breakdowns, (quick) examples, summarizing what you did at the end, etc. Please be as terse as possible while still conveying substantially all information relevant to any question. The user will ask questions if they don't understand.
Thinking of Mnemonics, Answering Etymological Questions
One of my one-off scripts for changing my flash cards was to add an etymology explanation to each Chinese word. People remember things better when there's context or a story that explains the association between things. Therefore, although I sometimes can't verify if the information from the AI is correct or not, having it craft a story to explain meaning is enough to help me remember words that don't make as much sense to me:
The prompt I use is below. It could be adjusted to even intentionally come up with stories for mnemonics. I feel this is an under-explored space (artificially generating mnemonic stories to remember things better).
The user is a native English speaker learning Mandarin (Taiwanese variant). They will give you a Chinese phrase and for each character, you will explain how it contributes to the meaning of the phrase. Be very succinct. If you don't know, prefix something like "I'm guessing that..." Do not be supportive. Be as straightforward as possible. Don't worry about formalities. Avoid introductions, conclusion, outline, breakdowns, (quick) examples, summarizing what you did at the end, etc. Please be extremely terse while still conveying substantially all information relevant to any question. The user will ask questions if they don't understand. Less is more.
Review Stories
Even with mnemonics, it's easy to forget how to use words if you don't see them in context. For this, I have some code that runs on its own to take a list of vocab and generate little stories that place them in context:

Using AI to take a list of foreign language words and craft them into simple stories in the foreign language (screenshot of Pleco)
In general, I'm quite pleased with the results, although it's not uncommon that the AI does not manage to squeeze all the words into the story. So, I tend to break up longer lists into small batches to send to the AI. The more words I ask to be included, the more likely some words won't appear in the story. Here's the prompt:
The user is a native English speaker learning Mandarin at the lower intermediate level. They will give you a list of traditional chinese phrases and grammar points, and you will use them to write a short story (a few sentences). Your story MUST include all the phrases/grammar points from the user. For the other words, stick to simple words like HSK 1-3, prioritizing easy words over ones that better fit the story. Avoid introductions, conclusion, outline, breakdowns, (quick) examples, summarizing what you did at the end, etc.
Speaking Practice with Multi-modal AI models
Some of the AI chat providers have a back-and-forth speech feature which use many different languages. However, so far, I haven't found it very useful for practice because it doesn't seem possible to adjust speed, regional accent, or speech complexity on the fly.

Using AI to have a conversation in a foreign language (ChatGPT)
I would guess that in most cases, if you are a non-native learner, you are better off using learning resources. I'm including this section because I'm excited about this space. I expect that other products already exist or will exist soon that specialize in this area.
Other tools
There are some systems in each language/culture that have straightforward rules but still require repetition for proficiency. You could create flash cards for these or code or even AI prompts to test you on examples from these systems. Some examples are:
- How to say a time in a foreign language
- How to say specific numbers in a foreign language
- Converting between the Chinese/Japanese numbering system that breaks numbers up by multiples of ten thousand (萬/万) instead of a thousand. For example, four million will be expressed as four hundred ten thousands.
- Choose the right word from a list of commonly mixed up words that best completes a sentence
I would love to hear about your systems if you have them! What works? What tools do you use? Email ulysse at ulyssepence.com.