perf: cap chat output tokens via ollama_num_predict to bound reply latency

Spoken (TTS) replies are 1-2 sentences, so an unbounded num_predict only
exposes the worst case where the chat model rambles or loops. Add an
ollama_num_predict config (default 512, 0 disables) wired into the reply
loop's chat call on both the native- and text-tool paths. The 512-token
headroom stays well above this app's short tool-call JSON, so capping never
truncates a tool call. This keeps the user's quality model instead of
downgrading it. Configurable in the container via OLLAMA_NUM_PREDICT.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
javis-bot
2026-06-23 15:33:45 +09:00
parent c189ce2e65
commit 5ee47827f3
7 changed files with 146 additions and 4 deletions

View File

@@ -2233,6 +2233,16 @@ def run_reply_engine(db: "Database", cfg, tts: Optional[Any],
has_tool_calls = " (has tool_calls)" if msg.get("tool_calls") else ""
debug_log(f" [{i}] {role}: {content}{has_tool_calls}", "planning")
# Bound worst-case generation latency: spoken answers are 1-2 sentences,
# so cap the chat model's output tokens. The default headroom sits well
# above this app's tool-call JSON, so capping never truncates a tool
# call. 0/negative disables it. See config.ollama_num_predict.
try:
_num_predict = int(getattr(cfg, 'ollama_num_predict', 0) or 0)
except (TypeError, ValueError):
_num_predict = 0
_chat_extra_options = {"num_predict": _num_predict} if _num_predict > 0 else None
# Send messages to Ollama — try native tool calling first, fall back to text-based
# if the model returns HTTP 400 (native tools API not supported).
_dump_tools_schema = None if use_text_tools else tools_json_schema
@@ -2242,7 +2252,7 @@ def run_reply_engine(db: "Database", cfg, tts: Optional[Any],
chat_model=cfg.ollama_chat_model,
messages=messages,
timeout_sec=float(getattr(cfg, 'llm_chat_timeout_sec', 45.0)),
extra_options=None,
extra_options=_chat_extra_options,
tools=_dump_tools_schema,
thinking=getattr(cfg, 'llm_thinking_enabled', False),
)
@@ -2273,7 +2283,7 @@ def run_reply_engine(db: "Database", cfg, tts: Optional[Any],
chat_model=cfg.ollama_chat_model,
messages=messages,
timeout_sec=float(getattr(cfg, 'llm_chat_timeout_sec', 45.0)),
extra_options=None,
extra_options=_chat_extra_options,
tools=None,
thinking=getattr(cfg, 'llm_thinking_enabled', False),
)