Secret Agent Man

I’d been looking at several LLM powered “agent” frameworks recently.  OpenClaw got a lot of buzz several months ago, spiked the cost of Mac Mini’s, and it seems reality doesn’t quite live up to the hype.  Peter Steinberger’s description of his OpenClaw1 creation in multiple videos, podcasts, and posts was he would wake up each day to discovery the agent had been working tirelessly throughout the night on projects, building things, discover things, bring him new opportunities, and learning and growing as it went.  Reddit and Youtube exploded with people snatching up Mac Mini’s for their high unified RAM / small form factor / modest cost, implementing their own OpenClaw’s, and telling everyone about their successes breathlessly.

I think my favorite “review” was this:

The next ClawdBot rebrand?

In the span of a few weeks ClawdBot went through several name changes, Anthropic blocked it from consumer level plans, Steinberger got a job with OpenAI, while people started to post their runaway token costs and concerns the agent was escaping containment, grabbing personal information, publishing personal information, and just generally running amok.

I have never tried OpenClaw because it seemed like an AI vibe coded slop privacy / security nightmare with a thick frosting of marketing slathered all over.  I understand the appeal of OpenClaw.  It would be so nice to have a little digital butler, looking at my cluttered desktop, helping tidy up, organize me, make some connections and surprising me in the morning with some new developments.  After all, where would Tony Stark be without Pepper Potts and Jarvis to keep him on the rails?2  I also understand how some semi-technical people would be dazzled by the promise of something that would work around the clock to make them money, all for the cost of a Mac Mini.

A short interlude about Chik-Fil-A.  I don’t like their politics and will not support them.  I’ve never once given them a single penny.  But, I have eaten food from Chik-Fil-A…  When a new located opened not far from my former workplace, they came by and left a HUGE platter of delicious chicken nuggets and sauces.  They have historically donated to our local Maker Faire, providing lunch for the makers.  Hide their branding and of course their food is going to be delicious – that’s the entire point of fast food.   The first year they provided lunch, I didn’t eat it – because I don’t like Chik-Fil-A.  The second year… I was weaker – but also more practical?  I was hungry, the kids were hungry, and although I had no problem paying for food at one of the many vendors, we’d been there a while, it was hot, the lines were long, and well, the food was right there.  I suppose the most subversive thing to do would be to take their food and toss it in the trash – or maybe shuttle their food to the kinds of people they despise.  But, I’m not in the habit of wasting or delivering food.  My own subversive little act was to eat the food – and resolve to never, ever, advertise for them or give them any money.

Back to LLM’s.  I have tried Hermes Agent, running in a docker container in a machine with very little personal information about me.  I’ve only been using it for a few days – and I think it has some real promise with some real caveats.

  1. The first caveat is that I won’t use any frontier LLM services because I can’t justify giving OpenAI/Anthropic/Google/Meta money for such things.  Whatever Google once was, whatever their motto might have been, they’re so far removed from that as to be a different animal entirely. 3 The obvious downside is that without access to a very fast, very big, and very powerful LLM, my Hermes Agent will absolutely be less useful than someone else’s instance.
  2. It will run in a Docker container on an isolated, budget machine, or not at all.

In practical terms, this means I’ve limited myself to either smaller and less capable local LLM’s that my machine can run or free tier API’s for various LLM providers.  I’m still fumbling my way around Linux / Ubuntu and already using LLM’s to get my bearings, so these resources for providing the LLM reasoning power for Hermes feels within bounds too.

As always, I simply don’t trust any LLM’s outputs.  I don’t trust their purported facts, claims, summaries, etc.  Even so, there’s no arguing they are capable of building systems.  Some family recently “fact checked” me using ChatGPT and I pointed out its merely a machine designed to provide them with the very next token of what they want to hear – not a system for giving them facts.  I feel like it’s probably impossible to build an AI / AGI without training it on facts, but relying on a token generator for facts seems foolhardy.  That said, I don’t have a problem relying on a system / set of processes / code base that I can inspect and verify works to arrive at a solution.

These “agent” systems are usually better called “agent harnesses,” since their best feature is offloading the work of monitoring, guiding, and nudging an LLM to perform a task.  The Hermes agent adds a lot of extra features – keeping things organized, keeping certain chats available to revisit later on, switching LLM’s between local / API based, but at it’s core it is saving me the time of just babysitting an LLM.

As understand these agents, the first thing they do is take a query, ask the LLM to break it into pieces, and then get to work on discrete elements.  It used to be that on long tasks ChatGPT would keep popping up a “Continue” button.  About two years ago I wrote a simple Chrome extension that was active on ChatGPT and would simply auto-click the “Continue” button whenever it appeared.  I think this is less a thing these days and ChatGPT will either truncate a reply or simply stop.  But, keeping the LLM on track for each small sub-task and spurring it to complete appears to be part of what the agent is doing under the hood.

I’ve tried several LLM’s to assist with writing code, with varying degrees of success.  The best OpenRouter free model I’ve used recently has been Poolside’s Laguna S2.1 with 118B parameters, a “mixture of experts” model with only 8B active at any given time.  I’ve been very impressed with it’s coherence on long tasks and overall quality of work – and it has been extremely helpful in setting up Hermes.  I haven’t tried a recent Qwen or Deepseek model on my very much underpowered system, but I plan on doing so soon.

My first goal with this system is to get it to just run a bunch of python scrips on a cron job.  I may need to build up a separate system entirely that only runs cron jobs, but which can have it’s roster of tasks manipulated by Hermes.  Too often the LLM gets involved and wants to interpret a query rather than run a static script, which just leads to more hassles.  Perhaps a frontier LLM wouldn’t have this problem – but I don’t plan on using them.

Project Jarvis
  1. Building a Jarvis-inspired voice activated LLM powered virtual assistant
  2. Building a Home PC Lab
  3. Secret Agent Man
  1. Well, Clawdbot -> Moltbot -> OpenClaw []
  2. NGL, I really hated Gwenth Paltrow’s Pepper Potts and would have liked nearly anyone else in that role.  Maybe it was the direction – or maybe just my dislike for Paltrow – but I found her bumbling, flustered character exhausting.  The comic book Potts was a capable, intelligent person in their own right.  Maybe there’s hope for a better person in a future reboot?  Hell, if they can recast Roddy, they can recast Potts. []
  3. I won’t even bore you with the full story of how Google promised a remediation for a Pixel 6 battery problem, bait and switched, then slowplayed it until everything expired. []

Building a Home PC Lab

Trigger warning:  This post (and potential series) is going to discuss some AI/LLM stuff.  That’s only a part of what’s going on, but if you hate all things LLM, then maybe this post isn’t for you.

Reasons for Building a PC

I haven’t built a PC in probably 25 years now.  Even then, I had the kind assistance of two friends who knew a lot more about PC building than I ever did. More recently I’ve been interested in building a PC for a variety of reasons:

  • The intellectual exercise of building something, mostly out of parts, all by myself
  • Having a PC running Ubuntu / Linux, something I’ve toyed with now and then, but never really tried in earnest.  I already eschew most closed source software in favor of open source alternatives1 , so moving to an open source operating system seems almost natural.
  • Some of my personal information currently resides on a computer I use for work – and I’d like to create a clean separation of these things for a variety of practical reasons.
  • Having an inexpensive and dedicated box would let me sandbox certain programs, try out different new ideas, and still let me access all this information and processing power remotely, if set up properly.
  • Yeah, I wouldn’t mind an Iron Man style Jarvis virtual assistant / butler, but the technology is still a fair bit aways as are my own skills and budget for such things.

Building in Parallel

I’ve taken to “building in parallel” for several recent projects.  With the recent remote temperature sensor system, I tried taking measurements with an infrared heat gun, then an ESP32C3 module with lots of wires, then several Wemos D1 Mini modules each separately sending data back to my PC.  While the ESP32C3 systems were still (mostly) working, I recognized some of the weaknesses and failure points and began working on the Wemos systems and didn’t take the ESP32C3 sensors offline until the Wemos sensors were up and running.  There was certainly overlap for a little while, but this also let me calibrate both systems.  I enjoyed working on these things, so building an entire second set of sensors in exchange for doubling the price and quadrupling the soldering wasn’t a horrible experience.  I’m reminded of a quote from Contact, “First rule in government spending: why build one when you can have two at twice the price?”

As with those sensors, I’ve had some automated projects running constantly lately.  Something that downloads a huge work calendar daily, a few simple reminders, something that sends me reminders over a messaging platform, and a few other assorted digital doodads.  I’m keeping all of these online, on my work PC, until I can get the Linux box going – then I’ll look forward to closing these down.

Pricing Things Out

As with nearly any learning experience, you end up paying for it one way or another – money, tuition, wasted attempts and materials, time.  Partially because I’m just starting out and partially because I’m fairly frugal,  I set a budget of ~$2502  If I’m going to spend any money at all, I wanted something that would work – but I’m not ready to drop $5k on RAM/GPU/newest processors.  My needs are still modest – and largely covered by my equally modest work computer.  It’s an Intel i7 with 32GB RAM in a very small mini PC case, handles email, big spreadsheets,  graphic programs, python projects, and even 3D modeling and rendering with OpenSCAD if you give it enough time.  It cost $550 before tax, new from Amazon, nearly 4 years ago, and is still going strong.

For this project I contemplated going with a fanless headless system, but these seemed to require special aluminum cases and appeared to be little harder to come by.  I thought about tracking down some e-waste resources, Facebook Marketplace, and Craiglist – but all of these require a fair bit of legwork and I feel like they’d also have more than a modest possibility of wasted time.  Any new PC would set me back at least $500 through either Amazon or Costco, so I turned to eBay since the rating system provides at least a modicum of quality assurance – if not in the product, at least the seller.

There are a ton of options for older PC’s that can be given a new lease on life with Ubuntu and some extra memory.  I’m still pretty biased against Dell, HP,  and Gateway for producing sub-par consumer grade computers for myself, family, and friends.  Some noodling about and half-hearted research suggested that these brands may produce significantly better enterprise machines than their consumer grade lines.  This only irritates me even more, if true.  This pretty much left me with Lenovo.

I ended up going with a “Lenovo ThinkCentre M70q Tiny i5-10500T 2.30 GHz” and paid a little extra to have the eBay seller customize it with 32 GB DDR4 RAM total, a 512 GB M.2 NVMe SSD, and throw in the antenna.  Besides being fairly accommodating and helpfully communicative, I went with this listing because it fell squarely in my price range / project budget, it already came with the power adapter, they were California, and it could ship very quickly.  While I could have easily spent another week or three trying to find a better deal on better and newer equipment, this was always going to be a project running on low end / older equipment and I valued the immediacy of getting to work over the incremental value of a better system.  Frankly, just not having to hunt for a compatible power adapter was a huge plus for me.

In the end I purchased the main system from the eBay seller, paid an extra $36 to make sure the system had 32GB of RAM, ordered a used 512GB SSD (they threw in the antenna) from them in a second purchase for $55, a SATA SSD enclosure to re-use an old 500GB SSD, and $7 to grab some HDMI dummy plugs off Amazon.  I knew the system would come with 16GB of RAM, but the benefit of “buying up” to 32GB also meant that I knew the machine wouldn’t have two 8GB sticks instead of a single 16GB stick.  I could later upgrade from 16GB to 32GB if I had a single 16GB stick to start – but having two 8GB sticks would mean I would later have to get two 16GB sticks.

Specs and Prices

Anyhow, for those of you playing along at home, here are all the parts for my $284.30 computer system.

PartCostShippingTaxTotal
M70q Gen 1(i5-10500T, 16GB, Adapter Incl., No SSD), upgraded to 32GB$185.99$5.93$14.41$206.33
M.2 SATA SSD to 2.5” SATA adapter enclosure$10.79$0.84$11.63
512 GB NVMe M.2 SSD, antenna$55.00$4.13$59.13
Dummy HDMI Plug$6.69$0.52$7.21
$284.30

I didn’t have to buy the SSD enclosure – but it seemed like a very inexpensive way to double the storage and repurpose my old drive.  I didn’t realize I’d need to get an HDMI dummy plug, or even what they were, until I tried to “remote” into the headless box and got a fairly ugly looking desktop instead of the slick Ubuntu desktop.  This was probably the least necessary of these purchases.  If I kept the system to the PC with the 32GB upgrade, ran the OS off my old SSD in the SATA enclosure, and picked up a $7 antenna off Amazon, the system would have only cost about $213.  The extra $59.13 doubled the hard disk space and enabled a more graphically pleasing interface.  It’s not much of a splurge and this was never a “build a PC for as little as possible” kind of a challenge anyhow.

The final system is probably on par with my existing 4 year old PC at roughly half the cost.  I think it was a “decent” deal and I have a system that I can use to offload a lot of projects.  If any of these projects end up requiring more processing power, I’m not even really “out” $285 since I can still keep using this system for other tasks (home automation, running daily scripts, etc).

And, yes, I’m trying to use this PC as a basis for a bundle of scripts I can deterministically interact with via voice input / output as well as certain LLM powered tasks.  First, a helpful comic.

And, that kids, is how AI killed human interaction

We’re probably hurtling towards dead internet theory.  I can’t search through Google or even DuckDuckGo anymore without having to wade through their AI summaries and then scroll past search results from AI slop.  Using ad blockers or setting up a PiHole to block ads and stop tracking from ever touching my PC may impoverish some otherwise worthy websites.  However, I simply don’t have to read every advertisement sent in the mail, on the inside of my grocery shopping cart, or every billboard.  Yeah, I hate the idea of AI companies boiling oceans of drinking water for their inscrutable purposes…

Reminds me of another quote…

There’s a quote I love by H.L. Mencken; “Every normal man must be tempted, at times, to spit on his hands, hoist the black flag, and begin slitting throats.”  What if the best way to filter out AI garbage is to use an LLM to do some of that filtering for me? 34

Searching through any search provider is kinda garbage these days, but there’s no reason I should have to wade through that AI garbage myself.  Gone are the days you can drill down to the kind of search results you want by simply adding “-negative_search_terms”, because there’s probably no financial reason for them to permit this.

But what if I created my own search function?  I recently tasked an AI with searching up 10 options for a certain product for me on Amazon and it did a mediocre job, finding 7 dead or unavailable listings.  But it also saved me a lot of time looking through dozens of pages of crap when I only needed to look through 10 crap listings.  With some tinkering, I think I could make a script that would identify negative search terms, perform the search as requested, then remove those that should have been removed with the negative search terms.  I could see this being incredibly useful for Ebay and Amazon purchases.

A preview for next time:  After some dithering, much watching of youtube videos, I’m going to give Hermes Agent a shot over OpenClaw.

Project Jarvis
  1. Building a Jarvis-inspired voice activated LLM powered virtual assistant
  2. Building a Home PC Lab
  3. Secret Agent Man
  1. LibreOffice, Thunderbird, OpenSCAD, etc []
  2. Is it really a budget if there’s a range?

    Words to live by

    []

  3. And, yes, I have considered the possibility that an AI company’s aim might be to make everyone distrust the entirety of the internet, then sequester everyone into their own little siloed version of digital reality, everyone watching slightly more targeted ads and Marvel movies than everyone else, and any attempt to use another LLM to filter shit out only results in more precise targeting… []
  4. I went to the hardware store yesterday and was told by someone who worked there in an orange apron that the entire store, inside and out, was covered in Flock cameras.  I think this bullshit surveillance is really starting to get to me. []

Building a Jarvis-inspired voice activated LLM powered virtual assistant

Just another day at the office
Just another day at the office

I’d like my computer to be smarter and more interactive and handle boring stuff for me and I’d also like to play around with some LLM / AI stuff… which brings me to this project.  I’ve got a ton of basic things I’d love for it to do – manage lists, reminders, some Outlook functions, some media functions, and then also be able to interact with me – all via voice commands.  Yes, you can do this with ChatGPT and probably others – but I am loathe to provide any outside resource with more of “me” (DNA, biometrics, voice, ambient noises, etc) than absolutely necessary.  Plus, I’ve been tinkering with these little LLM’s for a while now and see just what I can build out of them and with their assistance.

I’m not great at Python1 , so I admittedly enlisted the help of some very large LLM’s.  I started the main project in conjunction with ChatGPT, used Gemini to answer some basic questions about programming in Python syntax, etc, and Claude for random things.  The reason for keeping my general questions in Gemini versus ChatGPT was so that I could not “pollute” the ChatGPT flow of discussions with irrelevant sidetracks.  This was the same reason for separating out the Claude discussions too.  I find Claude reasonably helpful for coding tasks, but the use limits are too restrictive.

My kiddo asked me how much of the code was written by these models versus my own code.  I’d say the raw code was mostly written by LLM’s – but I’m able to tinker, debug, and… above all learn.  I’d rather be the one writing the code from scratch, but I’m treating these LLM’s like water wings.  I know I’m not keeping myself fully afloat – but I’m actually the one treading water, putting it all together, and learning how to do it myself.  Also… said kiddo was interested in building one too – so I’m helping teach someone else manually, and learning more that way.2

Ingredients

As with many of projects, I started by testing the individual pieces to see if I could get things working.  In order I started with validating individual pieces of the process:

  • Could I get Python to record audio?
  • Could I get Python to transcribe that audio?
  • Could I get Python to use an API to run queries in LM Studio?
    • Yep!  Using the openai API, I could use python to send queries to LM Studio after an LLM had been loaded into memory
  • Could I get Python to get my computer to respond to a “wakeword”?
    • Yep!  There’s another Python module for using  “wakewords” using PocketSphinx.  This was an interesting romp.  I found that I had to really tinker with the data being sent to the Wakeword to be properly recognized and then fiddle with the timing to make sure what came after the wakeword was properly captured before being sent to the LLM.  Otherwise, I ended up with “Jarvis, set a timer for 15 minutes” would become… “Jarvis, for 15 minutes” since the “Jarvis” would get picked up by the wakeword but the rest not caught in time to be processed by whisper.
  • Can I get Python to verbally recite statements out loud?
    • Yep!  I used text to speech using Piper.  However, this process took a while.  One thing I learned was that you needed not just the voice model’s *.ONNX file, but the *.JSON file associated with it.

Until this point, I had wanted to try running LLM’s with the training wheels from LM Studio’s API.  I really like the LM Studio program, but I don’t want to be dependent upon their service when I’m trying to roll my own LLM interface.  Python can run LLM’s directly using “llama-cpp-python” – except that it will throw errors on the version of Python I was running (3.14) and was known to work with a prior version (3.11).

This lead me to learning about running “virtual environments” within Python so that I can keep both versions of Python on my computer, but basically run my code within a specific container tied to the version I need.  Typing this command created the virtual environment within my project folder.  The second command will “activate” that virtual environment.

  • py -3.11 -m venv venv
    • This created the virtual environment, locked to Python 3.11
  • .venv\Scripts\activate
    • This activates the virtual environment, so I can start working inside it

Back to work!

The man's got a job to do
The man’s got a job to do

Building a Pipeline

This is where things really seemed to take off.  I was able to disconnect my script from LM Studio and use Python to directly call the LLM’s I’ve downloaded.  These were reasonably straightforward – and I was suddenly able to go from: Wakeword -> whisper transcribed LLM query -> LLM response -> Piper recited reply.  Then, it was reasonably easy to have the script listen for certain words, and perform certain actions (setting timers was the first such instance).

Optimizations, Problems, Solutions

Complicating factors
Complicating factors

Building something that kind worked brought me to a new and interesting  ideas, challenges, and problems:

  • The original cobbled together process was something like:  record audio, transcribe through Whisper, delete the recording, pass the transcribed statement to the LLM, give that statement to Piper, generate a new recording, play that recording.  However, this process has some obvious “slop” where I’m making and deleting two temporary audio files.  The solution was to find ways to feed the recording process directly into Whisper and feed Piper’s response directly to the speakers, cutting out the two audio files.
  • I realized that I wanted the script to do more than just shove everything I have to say / ask into an LLM – to be really useful, the script would have to do more than just be a verbal interface for a basic LLM.  This is where I started bolting on a few other things – like trying to call a very small LLM to try and parse the initial request to either:
    1. Something that can be easily accomplished by a Python script (such as setting a timer)
    2. Something that needed to be handled by a larger LLM (summarize, translate, explain)
    3. Something that maybe a small model could address easily (provide simple answer to a simple question)
  • I ran into some problems at this point.  I spent a lot of time trying to constrain a small LLM3 to figure out what the user wanted and assign labels/tasks accordingly.  After a lot of fiddling, it turns out that an LLM is generally a “generative” model and it wants to “make” something.  My trying to force it to make a choice among only a dozen “words”4 was really bumping into problems where it would have trouble choosing between two options, choose inconsistently, and sometimes just make up new keywords.  Now, I could come up with a simple Python script which just did basic word-matching to sort the incoming phrases – but it seemed entirely counterproductive to build a Python word-matching process to help a tiny AI.  I then tried building a small “decision tree” of multiple small LLM calls to properly sort between “easy Python script call” and “better call a bigger LLM to help understand what this guy is talking about” and quickly stopped.  Again, my building a gigantic decision tree out of little LLM calls was proving to be a bigger task, adding latency and error with each call.  I was hoping to use a small LLM to make the voice interaction with the computer simple and seamless and then pass bigger tasks to a larger LLM for handling, sprinkling in little verbal acknowledgements and pauses to help everything feel more natural.  Instead I was spending too much time building ways to make a small LLM stupider, doing this repeatedly, and then still ending up with too much slop.
  • And, frankly, it felt weird to try and lobotomize a small LLM into doing something as simple as “does the user’s request best fall into one of 12 categories?”  Yes, small LLM’s can easily start to hallucinate, they can lose track of a conversation, make mistakes, etc.  But, to constrain one so tightly that I’m telling it that it may only reply with one of 12 words feels… odd?
Tell me what I want to hear and this can all stop
Tell me what I want to hear and this can all stop

Over the last few days I’ve been tinkering with building an “intent classifier” or “intent encoder” to do the kind of automatic sorting I was trying to force an LLM to do.  As I understand this process, you feed the classifier a bunch of example statements that have been pre-sorted into different “intent slugs.”  The benefit of a classifier is that it can only reply with one of these “intent slugs” and will never produce anything else.  It’s also way faster.  Calling a small5 LLM with a sorting question could produce a sometimes reliable6 answer in about 0.2 ms, which is almost unnoticeable.  Calling a classifier to sort should enable a 97% reliable result within 0.05 ms.  This is so fast it is imperceptible.

I haven’t tried this yet.  I’ve built up a pile of “examples” from largely synthetic data to feed into a classifier, produce an ONNX file7 , and try out.  However, I wanted to pause at this juncture to write up what I’ve been working on.  I say synthetic data because I didn’t hand write more than 3,000 examples on some 50 different intent slugs.  I wrote a list of slugs, described what each one should be associated with, created a small set of examples, and then asked Gemini to produce reasonable sounding examples based on this information. 8 This list appeared pretty good – but needed to be manually edited and also tidied up.  I wanted to remove most of the punctuation and adjust the ways numbers and statements showed up, because I’m simply not confident that Whisper will be able to accurately match “Add bananas to shopping list” to “Add bananas to ‘shopping list'” to something that the classifier will correctly interpret.

As I tinker with this project… I’m also looking at how I might be able to extend it into further projects.  Not only might it be a great way to help me be more productive, but I might be able to create a really small version that could be put into a companion bot.  A little companion bot with limited space, power, inputs, and abilities to emote could be far more lifelike, independent, and non-deterministic in it’s responses and actions.

Project Jarvis
  1. Building a Jarvis-inspired voice activated LLM powered virtual assistant
  2. Building a Home PC Lab
  3. Secret Agent Man

 

 

  1. Yet!! []
  2. Thanks Mr. Fenyman! []
  3. Giving it limited context windows, limited tokens to use, highly restrictive system prompts []
  4. Make timer, list timers, make a reminder, add to a list, recite a list, media buttons, etc []
  5. ~1B parameter []
  6. Let’s say 65% reliable []
  7. Yes!  Just like the voice models!! []
  8. I know, more self-reflecting LLM garbage… []
Test