Flint needs constrained tool-call decoding outside rec (notes for other runtimes)

#11
by Nav8ha - opened

Thanks for Flint. Sharing what we found while running it in coding agents outside rec, in case it helps others who serve it.

1. Without a tool-call grammar, Flint invents argument names

rec runs Flint with --grammar flint, which keeps tool calls inside each request's tool schemas. With that grammar turned off (--grammar none), flint-int4 called OpenCode's read tool with path instead of the schema's filePath on 2 of 3 seeds of the same request. The tool definitions were in the prompt, so the model saw the right name.

Runtimes without tool-call constraints see this a lot. In OpenCode with mlx-vlm 0.7.10 (a 3-bit community build of Flint), 41 of 85 tool calls failed. The agent recovered through shell commands, so the tasks still passed, but slowly.

2. Constrained decoding must allow every stop token

generation_config.json lists four EOS ids, and Flint ends a tool-call turn on <|observation|>. A grammar that allows only eos_token_id (<|end_of_text|>) can't stop after a complete tool call. In our first attempt, one reply ran to about 19.6K tokens.

What fixed it for us

A grammar for the glm47-style format that limits tool names and argument names to the request's schemas (required arguments included), plus all four stop tokens. In the same OpenCode test, failed tool calls went from 41 of 85 to 0 of 50, with no measurable decode slowdown. The change is open for mlx-vlm: https://github.com/Blaizzy/mlx-vlm/pull/2571

Suggestion

A short "Serving Flint" note on the model card would save other integrators this debugging:

  • use constrained tool-call decoding, as rec does;
  • treat all eos_token_id values in generation_config.json as stop tokens, especially <|observation|>.

Sign up or log in to comment