DEV Community

Cover image for Why I Swapped the Weather Demo for a Movie‑Night Agent (and How You Can Too)
olav gerritsen
olav gerritsen

Posted on

Why I Swapped the Weather Demo for a Movie‑Night Agent (and How You Can Too)

Turning TMDB into a Gen-AI Plugin Playground (and having fun doing it)


Description

  • A Semantic Kernel agent that chats about movies, remembers what you’ve watched, and serves fresh recommendations.
  • Only seven tiny plugin functions (Top-rated, Search, Add / Remove / List Watched, Similar, Recommend) power everything.
  • Next steps: genre / year filters, streaming-service info, persistent cloud memory, shiny web UI.

1 Why TMDB + Plugins is a Developer’s Playground

Why it rocks What we get How the plugin maps it
Rich data Title, year, genres, poster, vote-average One C# function per endpoint returning pre-formatted strings
Open API No OAuth dance, generous free tier Simple HttpClient calls
Deterministic endpoints /movie/top_rated, /search/movie, … Predictable plugin surface
Built-in ranking TMDB already sorts by popularity + score We only need light post-filtering

2 Seven Skills That Ship Today

Ask the bot… It calls…
“Show me the current top 10 movies on TMDB.” tmdb.GetTopRatedMoviesAsync(take)
“Find movies with ‘star wars’ in the title.” tmdb.SearchMoviesAsync(query)
“Add Interstellar to my watched list.” memory.AddWatchedAsync(title)
“Remove Interstellar from watched.” memory.RemoveWatchedAsync(title)
“What have I watched so far?” memory.ListWatchedAsync()
“I loved Dune — anything similar?” tmdb.SearchMovieIdAsynctmdb.GetMovieRecommendationsAsync
“Give me five highly-rated movies I probably haven’t seen.” reco.RecommendMoviesAsync(top)

3 Architecture in 60 Seconds

  • Semantic Kernel handles DI and registers plugins.
  • The Stepwise Planner inspects your prompt, chooses functions, and iterates until it can answer in natural language.
  • Swapping the in-memory store for Redis or SQLite is one interface away.

3.5 Agent or Just Function Calls? 🤔

OpenAI function‑calling is simply the wiring—a structured JSON request that jumps from the LLM to your C# methods.The agent is the loop that keeps asking, “Do I know enough yet?” If not, it picks another plugin, calls it, updates context, and repeats until it can answer you like a human.

Reasoning – figures out which tool would help.

Tool‑use – invokes that plugin via function‑call.

Memory – stores and re‑uses what it learned.

Autonomy – iterates without any if/else in your code.

Put those four pillars together and you’ve got an agent!

4 Bug Diary: When a Space Killed the List 🔪

First test of “Give me five highly-rated movies I probably haven’t seen” spat back:

8,5
8,4
8,3
8,2

Only vote-average numbers survived!
Why? Every TMDB plugin glued its bullet lines with a space:

return string.Join(" ", lines);

The recommender later did:

list.Split(' ')
Enter fullscreen mode Exit fullscreen mode

Spaces in → spaces out → poof movie titles lost.
The universal fix was literally one character 👇

-return string.Join(' ', lines);
+return string.Join('\n', lines);
Enter fullscreen mode Exit fullscreen mode

…and two matching .Split() calls changed to '\n'.
Lesson learned: delimiters matter, and tiny plumbing bugs can wreck UX.


5 Stepwise Planning in Action 🤖✨

User ▸ I’ve watched Fight Club and Whiplash — recommend something new.

Planner ▸
  1. memory.AddWatchedAsync("Fight Club")          ✓
  2. memory.AddWatchedAsync("Whiplash")            ✓
  3. reco.RecommendMoviesAsync(top = 20)           → – Parasite (2019) 8.5 …

Bot ▸ – Parasite (2019) 8.5
      – La La Land (2016) 8.0
      – …
Enter fullscreen mode Exit fullscreen mode

No manual orchestration — the planner chained three plugins on its own.


6 Where We Go Next 🚀

🚧 Idea 🧩 How to plug it in
Year & genre filters Add optional parameters to TMDB plugin or a tiny post-filter helper.
“Where can I stream it?” Chain TMDB with JustWatch / Reelgood API; append platform badges.
Persistent memory Swap in-memory list for Redis / SQLite — same IMovieMemory interface.
Web UI shell Drop the same kernel into a React + Tailwind front-end.
Persona prompts Feed chat history (“movie night with kids…”) into a system message before recommending.
Poster images Use image_gen.text2im to generate missing posters on the fly.

Each is a thin slice — a new plugin or an extra parameter, not a rewrite.


7 Takeaway 🎬

Small, sharply-defined plugin functions + OpenAI Function-Calling + Semantic Kernel = conversation-native apps with almost no glue code.
TMDB makes it fun because the data is clean, the API is friendly, and talking movies is instantly relatable.

Fork the repo, swap TMDB for your favourite domain (books? restaurants?), and watch the same pattern shine.

Git Repo: https://github.com/olavgerritsen98/SemanticKernelAgentsDemo

Happy coding — and happy watching!

Top comments (0)