Tales from the jar side: Spring AI and Redis, A vibe coded lyrics trainer, Agent Underlord, and the usual toots and skeets
Found an old jukebox in prison, but it was filled with criminal records. (rimshot)
Welcome, fellow jarheads, to Tales from the jar side, the Kousen IT newsletter, for the week of May 11 - 18, 2025. This week I attended the graduation ceremonies at Trinity College (Hartford).
Spring AI + Redis
I mentioned last week that I recently ran a Spring AI training course that went well, and I was hoping to transform the demos into a series of exercises. That’s really what AI tools are for, given that the overall task fit good requirements:
I had an example at hand that I could give to the tool as part of the prompt
The process was routine and repetitive
All the steps were well-understood
Since I recently switched to the Claude Max program, I feel obligated to use it for as many small projects as I can while my subscription is still active.
I tried out that task early in the week. I don’t remember the exact prompt, which actually brings up one of my issues with Claude Code:
Unlike the app or the website, Claude Code doesn’t store your previous conversations anywhere. If you want to preserve them, you have to use whatever mechanism is inside your command line tool.
On my Mac, I use iTerm2 for my command prompt using oh my zsh for the shell. That means there is a log command available, when I remember to use it. Unfortunately, this week I both forgot to use it, and, the one time I remembered, I can’t remember where I saved the log file. And so it goes.
At any rate, after converting the existing labs, I couldn’t leave well enough alone, of course, so I had to add more. That worked and it didn’t. The simple extensions I had in mind worked without an issue, but when I tried to add some RAG examples, I ran into problems. It turned out Claude Code didn’t understand how input documents are supposed to be processed for RAG.
It’s a three step process:
Read the document using some kind of document reader. The Spring AI project includes both a pdf reader (multiple one, actually, but I took the one with that name), and a Jsoup document reader for parsing web pages.
Split the document into chunks using a text splitter.
Add the documents to a vector store, which also does the embedding into vectors.
I learned this week I really need to use one of their document readers, or the input files aren’t converted into a list of documents properly. The AI certainly didn’t understand that. This was one of those cases where the AI goes round and round in circles, trying to fix things and undoing the results, burning tokens along the way. Once I realized what was happening, I stopped it and did what I should have done — figured it out and wrote the code myself, then explained the result to the AI.
Once I had the RAG part working with a simple vector store, I then wanted to switch to a real database. The problem I encountered then was that some of the vector databases weren’t compatible with the updated version of Spring AI. I fought with Chroma for a while before giving up. Then I looked at a couple of others, but I didn’t want the students to have to worry about registering a key or deploying to the cloud or anything like that.
What eventually worked was to use Redis, a simple key-vector store which is one of the most popular NoSQL databases in the world. Even better, it turned out I didn’t even have to install Redis or write any complicated code to use it. All I did was start it up in a docker container:
docker run -p 6379:6379 redis/redis-stack:latest
That downloads and runs the latest version of Redis. Then, for Spring AI, all I had to do was add a few settings to application.properties:
# Redis settings
spring.ai.vectorstore.redis.initialize-schema=true
spring.data.redis.host=localhost
spring.data.redis.port=6379
spring.data.redis.username=default
spring.data.redis.password=
With that setup, I didn’t even have to create a VectorStore bean or anything like that, because the Spring AI starter for the Redis vector store took care of all of that for me.
implementation("org.springframework.ai:spring-ai-starter-vector-store-redis")
I ran into a problem that it took at least a minute or two to load the pdf I gave it and save it to the vector store, and I didn’t want to do that every time I ran. The solution to that turned out to be executing a simple similarity search on the vector store to see if the data I wanted was already in there, and, if so, I could skip populating it again. As long as I left the docker container running, everything was good.
I’m still going to have to go through the exercises one by one in practice to make sure they work well together, but at least now I have a decent set of exercises I can share with the students.
In fact, that process worked so well, I plan to repeat it for my other training courses. I already tried it for my upcoming class this week. I’m sure I’ll have something decent in time for that course to start.
Lyrics Trainer
I also mentioned in last week’s newsletter that I was preparing for a concert this weekend at First Church in Glastonbury, CT. One of the challenges I faced for that concert is I needed to memorize one of my songs, as the rest of the soloists were doing. My solo was This Is The Moment, from Jekyll & Hyde, and I’m afraid memorization isn’t as easy for me as it used to be.
I figured this was one of those opportunities to try out vibe coding, which is the rather pejorative term used by developers for describing what you want to an AI and having it implement it however it wants. For me, that meant coding in HTML, CSS, and JavaScript, all of which I have a reasonable knowledge of but don’t use actively.
I started out using OpenAI’s o3, which is its best reasoning model. That gave me something quickly. I then switched to JetBrains Junie, because I want to try out that product, but the results were only decent. I finally went back to Claude Code again, which is still my most productive AI agent.
Here’s a quick illustration of the result:
That’s a very quick demo, showing night mode, with manual Next and Previous buttons, and a Play button that advances the lyric every 2 seconds. I can also click the “Upload Lyrics” button and point it to a text file, and the player will use that instead.
There are three additional cool features:
The display works nicely on mobile as well, with swipe gestures. It’s not a mobile app, though — you have to load it in a mobile browser, but as long as your phone is on the same network as your server, it works fine.
It uses a service worker, which means it has an offline mode. I don’t even have to be running the server for it to work at all, which is pretty cool.
It also persists the position, settings, and custom lyrics to local storage.
To top it off, after the initial experiment, I switched from JavaScript to TypeScript, which is a language I don’t know.
This is where we are with AI agents. I’d like to think that all my years of software experience had something to do with this, and maybe it increased how quickly the product was developed, but when my wife asked me if I wrote it, I hesitated. The answer is no. Claude Code wrote it, after some design work by o3 and some evaluations by Junie. I told it what I wanted, identified problems as we went along, and made some high level decisions, but if I’m honest, pretty much anybody could have done that.
This is seriously cool, a lot of fun, and pretty scary as far as my profession is concerned. I can see that as the programs grow more complex, the AI’s may not handle it well. Then again, neither would I, and we’re only at the beginning of all this. Once again I guess I’m glad I’m not that far away from retirement.
(If you want to try out the program, it’s located in this GitHub repository. As the README file (also generated) says, run:
> npm run build
> npm run serve
and load the program on localhost port 5173. I’m probably going to continue to tweak it, but you’re welcome to play with it if you think it might help you.
Agent Underlord
I haven’t made a video for the Tales from the jar side YouTube channel in a while, but now that my semester is over I expect to get back to that. Just as I worked out a basic script for a new video, however, Descript (my video screen recording software of choice) released a new update with — you guessed it — more AI support.
What they’ve added is something called Agent Underlord. Sigh. That continues the trend of AI companies being horrible at naming things, but so be it. Descript asked me to record my initial experiences with the product, so I turned on their screen capture and dove in.
I recorded myself talking to a camera, and then asked the agent to:
Break the recording into scenes
Remove all the filler words, shorten word gaps, and eliminate duplicate takes (which the existing AI tools used to do)
Change the layout appropriately
Select and add alternative images and videos (what we call B-roll) wherever helpful
Add music snippets and sound effects
The result isn’t anywhere near publishable. I mean, it’s okay, but not great, and still needs a fair amount of work. I don’t know yet whether it will ultimately save me much time. We’ll see. I do hope to release a new video this week, with the working title, Generative AI Tips All Java Developers Need To Know, so look for that in the next few days.
Trinity Graduation
I wasn’t going to go to the Trinity graduation, but my wife convinced me that attendance was more to support the students than anything else. With my own degrees, I had the opportunity to attend four graduations, but only went to two of them. I attended my undergraduate ceremony, partly because I was a double major, partly because it was a big deal, and partly because my parents would never have forgiven me for skipping it. As part of my Ph.D. program, they throw in an MA when you pass your general exams, and though I was glad to get it, that didn’t seem worth a ceremony. I would have attended my Ph.D. graduation, but I finished in October and took a job several states away, so it seemed silly to go back there six months later. Finally, after working several years, I went back to school and got my MS in computer science at night, so I went to that graduation along with my wife, but that was for working professionals and didn’t bother with robes or anything.
The bottom line was that today dawned bright and clear, so I decided to go.
That’s the first time I ever processed as a faculty member, so that was interesting. I was glad to wave to the CS seniors, and I got to say nice things to one of their parents. The keynote speaker was our current CT governor, Ned Lamont, and he was fine. All in all it was a decent experience. Maybe I’ll go again next year. We’ll see.
Broadway Extravaganza
Yet another event I mentioned last week is that yesterday (Saturday, May 17), I participated in a musical event at First Church in Glastonbury, CT. The show was the final entry in their Music in the Meetinghouse series for the year, this one called Broadway Extravaganza. Both my wife and I had a lot to do and spent a lot of time this week preparing, and everything went well.
I believe there was a recording, but it’s not available on the website or their YouTube channel yet. If it shows up soon, I’ll put it in next week’s newsletter.
Toots and Skeets
Nap time
Clever, but I think I need to go lie down now.
Unexpected consequences
Hard to go more wrong than that.
Old song reference
I also suspect her number isn’t 867-5309, either, but I still recall that more readily than my own phone number.
Good hiding place
That joke could have gotten very dark, so I’m glad it went another way.
System messages
In case you don’t get the reference, this week Grok (the AI from Elon at twitter) decided to start answering lots of questions with unrelated comments about a mythical white genocide in South Africa.
X (or xAI, but whatever) tried to explain:
Yeah, right. Unauthorized. Who could possibly (1) have the authority to do that and (2) be stupid and clumsy enough to have it appear on totally unrelated posts all over twitter? We all know it was Elon, so just admit it and move on.
Remember, your answer must be in the form…
Got him good. Got him real good.
Tariff nonsense
That’s all I’m going to say about that, other than this is a continuing story that is not going away any time soon.
Except for this:
Or this:
That’s enough, or maybe more than enough.
Speaking of trade deficits
Have a great week, everybody. :)
Last week:
Musical performance
This week:
Functional Java on the O’Reilly Learning Platform