7B Model Chokes on Multi-Call Comparisons — Here's How I Fixed It
The setup: a PyBaMM digital twin simulating an LG M50 21700 cell, wrapped as six MCP tools over stdio. A LangGraph ReAct agent backed by qwen2.5:7b via Ollama picks the tools and narrates the results.
The six tools:
cell_info— static cell descriptionsimulate_discharge— constant-current discharge (runtime, capacity, energy)simulate_cccv_charge— CC-CV charge (charge time, energy input)compare_charging_strategies— ranks multiple charge rates in one callcompare_discharge_rates— compares multiple discharge rates in one callsimulate_degradation— capacity fade over N cycles via SEI growth
Single-tool questions worked great from day one. Ask "how long at 1C?" and the agent calls
simulate_discharge(c_rate=1.0), reads the result, and answers. Reliable.The break came with comparisons. Ask "2C versus 0.5C" and the natural ReAct pattern is two sequential simulate_discharge calls — one per rate. On qwen2.5:7b, this reliably failed. The model would chain one call, get the result, then either stop or hallucinate a second answer. No error thrown — just a confident, well-formatted response missing half the data. Exactly the kind of quiet failure the physics-grounding was supposed to prevent, just moved up one layer from number generation to tool orchestration.
It wasn't the only rough edge. llama3.1:8b at one point printed tool calls as literal JSON text instead of invoking them, so no simulation ran at all — that's what pushed me to qwen2.5:7b. Separately, the agent would sometimes speculate about why a number looked a certain way: labeling delivered capacity above the 5.0 Ah nominal rating as "inefficiency" or "over-discharge" when running above nominal capacity at gentle rates is just normal cell behavior.
The root issue isn't model size — it's planning horizon. A two-call comparison isn't one decision; it's several in sequence: call tool A, hold its result in context, decide to call tool B with different arguments, hold that result too, then reason over both. That's a chain the 7B model loses track of.
The fix was collapsing comparison logic into single-call tools. Instead of asking the model to chain simulate_discharge twice, I built compare_discharge_rates and compare_charging_strategies to run multiple simulations server-side and return a ranked result. The model now makes one call, gets a complete answer, and there's no multi-step planning to fail.
The prompt I use for the agent:
You are a battery engineering expert assistant. You have access to simulation tools that run real electrochemical models. Always use the appropriate tool for the question asked — never guess at numbers. If a comparison is needed, use the comparison tools. Only speculate about results after you have the data. Keep answers concise and grounded in the simulation output.This isn't just about smaller models — it's about designing tools that match the planner's actual capacity. Every tool I build now goes through the same filter: what's the minimum number of sequential calls a 7B model can reliably chain? If the answer is more than one, I fold the logic into the tool itself.
