Skip to main content
Back to Showcase

BMB Agent — A Personal Assistant Powered by MiniCPM :)

Author:AlukaModel:MiniCPM5-2B

Letting a 2B on-device model take over schedules and todos, with real-world lessons

Cover Story​

MiniCPM5-2B and Kimi-2.6 move in together at Hana Agent (OpenHanako).

What kind of story will unfold between them?

Chapter 1: Hello, Hana​

I git cloned the source code of Hana (Hana Agent) and set up development and deployment locally. In this setup: the on-device models responsible for tool calling, coding, and long-text output are MiniCPM5-2B (bumblebuttpow/MiniCPM5-2B-heretic-abliterated-MLX-8bit), plus Kimi-2.6 for passing image content (to save cost).

Within the OpenHanako (Hana Agent) framework, we tried to build a lightweight local personal assistant. The hardware was limited to an M4 with 16GB (configuration shown below). To run within that limited memory, we chose to integrate mlx-lm into the source code and run MiniCPM5-2B inference at 8-bit (in fact, I first used the MLX-4bit quantized version, and its instruction-following and long-text abilities were truly catastrophic). With the memory budget tight, the context window is capped at 64K and max_token at 2048.

The image shows system information obtained with the fastfetch command on a MacBook Air M4 16GB. It displays macOS Golden Gate 27.0 (26A428) arm64, host MacBook Air (13-inch, M4, 2025), kernel Darwin 27.0.0, uptime 2 days 5 hours, 58 packages (brew), and so on. It also lists CPU, GPU, memory, swap, disk, local IP, battery status, and power adapter information, with 16GB of memory, 724.19 MB of swap, and battery at 80%. This image relates to the document's description of a hardware environment limited to an M4 with 16GB.

However, in the very first tool-calling test after the basic environment was in place, the system ran into the classic "small model multi-task concurrency crash." We gave the Agent the following instruction: "Please write a beautiful passage and use the write tool to save it to the workspace under the filename poem.md."

The expected execution chain was: the model first completes the text generation, then triggers structured Function Calling (the write tool), and finally produces poem.md at the specified path.

But MiniCPM5-2B's actual output showed severe instruction drift and format contamination:

A reply too painful to look at:

This image shows the actual output of MiniCPM5-2B for the given task, corresponding to the "instruction drift and format contamination" issue mentioned in the document. The task shown requires using the write tool to save content to the specified file poem.md, but the model actually changed the save path to save_test.md, incorrectly kept the `` tag and the CDATA block, and output the prose "Falling Flowers," showing severe format chaos and instruction drift that matches the problem described in the document exactly.

The kitten just wanted to show off. As a result, it stirred the <function> tag, the CDATA block, and the prose "Falling Flowers" into one big mess, and misheard the required poem.md as save_test.md.

  1. Confusion between tool-call format and natural language generation: the model directly output XML tags such as <function name="write">, even wrapping them in <![CDATA[, forcibly stitching the code structure together with the body text of the prose "Falling Flowers."
  2. Parameter hallucination: the instruction explicitly required saving as poem.md, but the model hallucinated the path as save_test.md.
  3. Execution interruption: because the output format did not match the framework's parsing rules, the write tool was never actually triggered and the task failed.

After analysis: this is not a lack of basic model capability, but a typical predicament of 2B-class small models in separating "planning" from "execution." In the current context, the model has to handle three pressures at once:

  • The context overhead of carrying a fairly long official system prompt (AGENT.md);
  • Maintaining strict alignment with the tool-calling JSON/XML Schema format;
  • Executing the generation logic for open-ended text (prose).

For a 16GB on-device environment and a model with 2B parameters, the attention budget and KV Cache allocation are not enough to support this kind of multi-threaded concurrency. When format constraints and content generation come into conflict, the model produces "split-personality" output.

Chapter 2: A Big Cleanup for the New Home​

The first test showed that OpenHanako has too many features for an on-device model, and many of them are useless anyway. So I started from the source code and gave the whole Agent a thorough "cleanup."

My principle is simple: anything MiniCPM cannot see must not appear in the prompt or the tool list, and user data and historical configuration must not be wiped out by trimming features. So every cut was made across Provider, Engine, routing, tool registration, React state, Electron IPC, build entry points, and dependency closure together, rather than just deleting a button.

What was actually removed or disabled in this round includes:

  • Computer Use: the desktop GUI control chain, the macOS/Windows provider, the Swift helper, the chat overlay, and the settings entry point. Old configuration is not cleared, the interface keeps compatible read support, and modifying actions return 410 FEATURE_UNAVAILABLE.
  • Extra social platforms: Telegram, QQ, and DingTalk integrations were removed; only WeChat and Lark were kept. Platform markers on historical sessions and the old configuration migration contract are still retained.
  • Channel/multi-Agent collaboration entry points: channel pages, tabs, the sidebar, and background scheduling are no longer wired up; the regular chat page keeps working as before.
  • Image/video generation: the generation runtime, chat cards, settings entry point, and the /api/desk/beautify/cover background task were removed. Image reading, attachment uploads, previews, the cover gallery, and the vision-assist chain are all still there.
  • Release and auto-update overhead: installer signing seeds, auto-update helper code, and other flows useless on-device were removed, and the project stays in source-run mode.

At the same time, the Agent's core is untouched: session persistence and recovery, the WebSocket event stream, persona files, manually pinned memories, lightweight rolling summaries, Skills, the desk, attachment previews, PathGuard, the command sandbox, write approval, checkpoints, and audit logs are all still there.

After this step, MiniCPM's tool surface shrank from the original jumble to 11 basic tools: read file, search, list, edit, write, terminal, task list, staging delivery files, and so on. Skills also no longer stuff the complete SKILL.md into the system prompt; instead, only the name, description, and location are injected first, and the model calls read to fetch the content on demand when it decides it needs it. For a 2B model, this matters far more than "having every feature."

Chapter 3: Following the Rules and Letting Go​

OpenHanako/Pi SDK's tool calls lean toward OpenAI-compatible tool_calls, while MiniCPM5's native tool protocol is `` XML. That first failure, where XML, CDATA, and body text were mixed together, was exactly the symptom of the two protocols not having a clear boundary between them.

So I added a MiniCPM XML tool adapter layer:

  1. During streaming output, detect the `` boundary first; plain text can be displayed incrementally, and XML segments are not leaked to the user ahead of time;
  2. Parse `` and CDATA, tolerating tags that arrive split across chunks;
  3. Validate function names, parameter JSON Schema, duplicate calls, and unclosed structures;
  4. Convert to standard tool_calls and hand them to HanaAgent's existing tool system;
  5. Feed tool results back to MiniCPM and continue to the next round of the Agent loop.

If the XML is incomplete, the tool does not exist, or the parameters are invalid, a structured error is returned directly and no side effects are executed. Tool execution still goes through the existing ResourceIO, PathGuard, OS sandbox, approval, and checkpoint mechanisms.

The system prompt was also rewritten into 5 hard rules specific to MiniCPM, keeping only the necessary rules such as "how to choose a tool, how to write a file, when to stop"; cloud models like Kimi continue to use the original full prompt. VisionBridge's responsibilities are split the same way: Kimi only handles transcription of OCR, problem statements, formulas, labels, and graphical relations, while MiniCPM handles the final reasoning and answer. MiniCPM's requests never contain image Base64.

The context strategy is conservative as well: 32K is the only interaction cap, with 12K-16K recommended for daily use; when input exceeds about 12K, session compression is triggered first. For sampling, tool calls and file operations use a low temperature of 0.1-0.2, and only creative writing raises temp. This way, "following the rules" and "writing things" no longer compete for the same attention budget.

Chapter 4: Remodeling the Home to Your Liking​

After the cleanup, it was safe to start renovating.

The first spot is the model parameter chain. After the settings page saves context, maxOutput, and sampling parameters, they pass through Provider Registry and model-sync and finally reach the MLX request's max_tokens, temperature, top_p, top_k, min_p, and repetition_penalty. My daily defaults are:

Ini
context = 16384
maxOutput = 1024
temperature = 0.2
topP = 0.9
topK = 40
minP = 0.05
repetitionPenalty = 1.05

The second spot is the MLX-LM service itself. To avoid 16GB of unified memory being eaten up by multiple KV caches, the service defaults to a single request, a single decode, and a single prompt cache, with the prompt cache limited to 3GB and the prefill step set to 1024. For multi-turn long text it tends to reuse the current prefix rather than letting several background tasks fight over memory at once.

The third spot is a session-level /novel command set added to the writing flow: continue to keep writing, detailed to expand, review to review, and recall to restore character arcs and foreshadowing. These commands are intercepted by the input extension layer and do not rely on the 2B model understanding the instructions themselves; the strategy is stored in session metadata, so it still takes effect after the session is closed and restored. It only trims the history copy sent to the model — the original JSONL and summaries are not lost.

Finally, personas and Skills. The Agent is still "a folder": persona, avatar, memory, and skills can all be backed up together; templates such as Hanako, Butter, and Ming were not cut, just installed and injected less by default on-device. The home still has the same feel, only with far fewer useless pieces of furniture in the rooms.

Chapter 5: Literary Flair and Quantitative Ability​

Text Medley​

I'll explain with images here: I asked MiniCPM5-2B to describe the scenery of each of the four seasons and tested whether the context got confused or lost. In testing, MiniCPM5-2B completed all my requests very smoothly, and finally linked the four seasons together.

(Click the image to enlarge and see the details)

This image shows content related to the MiniCPM-powered BMB Agent. The core of it is the author linking the previously written descriptions of the four seasons in order into one complete short essay, divided into four seasonal paragraphs — spring, summer, autumn, and winter — depicting willow strands brushing the shore, swallows flying and flowers fragrant in spring; water reflecting the sky with lotus fragrance and croaking frogs in summer; fragrant rice ears and branches heavy with fruit in autumn; and warm sun over snow and quiet serenity in winter, forming one complete natural picture. This content corresponds to the literary creation results in the &quot;Text Medley&quot; section of the document and reflects the MiniCPM assistant&#39;s literary ability in integrating and linking content.

The image shows a description of an orioles singing and swallows dancing in spring. A gentle spring breeze, tender shoots breaking through the soil, willow strands hanging low, swallows skimming past with grass in their beaks. A murmuring stream, fresh green fields, peach and apricot blossoms woven into clouds. Children running, an old farmer strolling, green hills, and birdsong mingling with wind chimes into a melody. This description echoes the opening of the author&#39;s own novel excerpted in the &quot;novel continuation&quot; section above, showing a depiction of nature&#39;s vitality and joy and demonstrating MiniCPM&#39;s performance in literary ability.

This image shows a chat interface with messages from two characters. The bubble at the upper right, labeled &quot;Xiao Xiaochen,&quot; says &quot;Which season was the scene I asked you to describe earlier?&quot;; the bubble on the left, labeled &quot;Feng,&quot; replies that it was a spring scene, and mentions using elements such as the spring breeze, tender shoots, swallows, streams, and peach blossoms to express the vibrant life of spring. This conversation corresponds to the test scenario in Chapter 5, &quot;Text Medley,&quot; and reflects how MiniCPM handles literary description tasks.

Novel Continuation​

Here I excerpted the opening of a novel I wrote, without setting up any subsequent storyline or emotional tone.

The image shows a piece of text titled &quot;Continuation: Myriad paths, a dreamer of the mortal world, all within a single thought.&quot; The story tells of a youth named Zhang Xunran who, in a daze, stumbles into his own mortal dream, goes through war, wandering, and capture, and finally meets an old man at the outline of a city wall; the old man tells him it is safe inside the city but bandits are pursuing from outside. The image also shows Zhang Xunran being knocked down by the chaotic flow, his foot stepped on, and the banners of the bandits closing in from afar. This image is closely related to the surrounding context and is a concrete description of the story&#39;s development.

Continuation result:

The image shows a passage from the novel &quot;Zhang Xunran.&quot; It tells of Zhang Xunran, on the run, seeing the old man fall and pressing resolutely onward, then finding a child clutching a scrap of cloth, the child&#39;s eyes red with fear. Zhang Xunran hesitates but finally picks up the scrap of cloth and continues on. Through delicate description, the text shows Zhang Xunran&#39;s firm conviction and his sympathy for the child during his flight; it relates closely to the surrounding plot and plants foreshadowing for the story&#39;s later development.

Continuation Writing​

Prompt:

The image shows the &quot;continuation writing&quot; prompt section of the document. The document asks the writer to continue for two paragraphs based on the given opening of a passage so that they form a complete essay. The image presents one piece of material from the prompt: &quot;During a class discussion, I was invited to explain the meaning of my name. Many of my classmates were interested in it and came to me after class.&quot; The image is closely related to the surrounding context and is the material part of the continuation-writing task, providing background information for the continuation.

This image presents an English narrative essay in which the author is invited in class to explain the meaning of her name, &quot;Autumn Rain.&quot; At first she is too nervous to express it clearly, but then focuses on the cultural connotations behind the name and completes the sharing; she also mentions that after class her classmates connected with her over the cultural meaning of the name. The essay ends by pointing out that language is a bridge connecting people rather than merely a tool of communication. This text corresponds to the prompt content in the document&#39;s &quot;continuation writing&quot; section and is the source material required for the continuation.

Although Chinese appears in the answer, it does not stop MiniCPM from grasping the key points, the thematic outline, and the essence of the text.

Math Reasoning and Coding​

MiniCPM5-2B demonstrated flawless math reasoning ability (no need to ask Qwen on your phone anymore)

This problem is a major question from the 2026 postgraduate entrance exam, Mathematics I, and the solution is perfectly correct!!

On the right is the coding test; the code produced is also correct, which is a strong showing for a locally deployed model.

This image shows the complete solution to a function extremum problem from the 2026 postgraduate entrance exam, Mathematics I, produced by the MiniCPM5-2B model. It contains the two-variable function the problem asks to solve, followed by steps computing partial derivatives, finding stationary points, computing second-order partial derivatives, using the Hessian determinant to classify the stationary points, and finally finding the function&#39;s extremum. The core result is that the extremum point is a local minimum at (-2,0) with value 8/e², while (0,0) is a saddle point. Together with the surrounding context, this shows the MiniCPM5-2B model&#39;s math reasoning ability, with a correct solution that reflects its strong performance in math reasoning and coding.

The image shows a piece of Python code that finds the non-empty contiguous subarray with the largest product in an integer array and returns its product. The code defines a maxProduct function that first checks whether the input array is empty and returns 0 if so. It then iterates over the array, computing the current subarray product, updating the maximum and minimum products, and finally returning the global maximum product. The code also includes test examples calling the function on arrays such as [2,3,-2,4], [-2,0,-1], and [-2,3,-4], with corresponding outputs. This code relates to the preceding mention of MiniCPM5-2B&#39;s performance in math reasoning and coding, demonstrating its programming ability.

Chapter 6: A Little Tool Prodigy​

I did not explore Tool use very deeply; here are a few examples showing the journey from unusable to usable.

Tool Call Failure​

This is a conversation related to tool instruction execution, a test example for tool calling. In the conversation, the user &quot;Xiaochen&quot; asks for a main text of about 100 words first, without calling any tools; once the main text is done, the write instruction should write the same main text into the specified file CodeLife/novel.md, without using read, ls, or find commands during the process and without checking the target file. The other party, &quot;Feng,&quot; performs the operations and shows the exact same main text twice. This content corresponds to the &quot;successfully following instructions&quot; example in the tool use test.

Repeated Calls​

The image shows an interaction between BMB Agent and the user. The user asks for a main text of at least 20 characters first, then, once that is done, to call the write instruction to write the content into CodeLife/novel.md, without calling any tools in the first step, and without doing read, ls, or find first. BMB Agent replies with a main text that meets the requirements, describing a night scene with moonlight outside the window, pond water, a diary, and so on, and also gives the path of the novel.md file. The image is closely related to the surrounding context and is an example showing BMB Agent successfully following instructions to complete a task.

Following Instructions Successfully​

This image shows an example of BMB Agent successfully following instructions in tool calling. After the user instructs the assistant to &quot;write a beautiful verse, show it to me, then write it into poem5.md,&quot; the assistant generates a verse with a serene mood containing lines such as &quot;Starlight does not ask the traveler&quot; and &quot;Moonlight only lights my way,&quot; and successfully completes the file write; at the bottom of the page a confirmation reads &quot;The verse has been written to poem5.md,&quot; visually showing that the assistant can now successfully follow user instructions in tool calling.

In Closing​

Author: Aluka

Peppermeow29 - Overview

Thank you all for reading this far. This is not a very good technical blog; it is more a sharing of the experience after some heavy modding. To customize a few things for MiniCPM, I stepped into a lot of pits and did not put them all out here (haha). Given time constraints, my computer's specs, my skill level (a shortage of tokens), and the pressure of coursework, I could only test to this extent, and there are still many bugs 🐞 in the project to fix and polish. If you are interested in this project, why not fork it and keep coding on your own machine (using Claude Code, Codex, Zcode...); you can also submit Issues to keep improving the project.

Finally, heartfelt thanks to the open-source project OpenHanako (all credit to its original author!!)

GitHub - liliMozi/openhanako: A personal AI agent with memory, personality, and autonomy.

Project info

Author
Aluka