Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

fix(llm): handle_no_tool_calls 仍会落盘空 assistant 行——#168 的同族遗留通道

オープン
#196 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 1 日以内に返信

まだ誰も着手していません。

評価

難易度
3/5
見積もり時間
1〜2日
初心者へのやさしさ
68/100
issue の種類
バグ
明瞭さ
明確に書かれている
活発さ
活発
技術スタック
rust
領域
backend

調査の方向性

Read src/run_core.rs around handle_no_tool_calls (lines 835–857) and compare its empty-content handling with the has_persistable_interrupt logic from issue #168. Add a test for a normal stop with empty content and no tool calls, then run cargo test --lib and cargo test --test invariants. Done means the transcript has no empty assistant row, with the predicate covered by an assertion or equivalent reasoning.

索引モデルが issue の本文から書いたものです。

説明

优先级 P3 · 依赖:无(同族于已修复的 #168)

基线 HEAD = e9e314ec

Summary

#168 修复了「中断在 tool_call 阶段落盘空 assistant 消息」的中断路径,但交付说明
(infra4agent#8)已指出:同族通道 run_core::handle_no_tool_calls 未被处理,
且当时标记为「超范围,故未动」——但没有开跟进单。本单补上这个跟踪项。

src/run_core.rs:835-857:

fn handle_no_tool_calls(&mut self, completion: &Completion, step: usize) -> Option<FinishReason> {
    if !completion.tool_calls.is_empty() { return None; }
    let mut msg = Message::assistant(completion.content.clone());   // ← content 可为空串
    msg.reasoning_content = completion.reasoning_content.clone();
    self.push_message(step, msg);                                    // ← 无条件落盘
    ...
}

即:正常停止(非中断)且 content 为空时,仍会落盘一条
{"role":"assistant","content":""} 的 transcript 行。

为什么目前危害低(但不该长期如此)

#168 的三层防线已把「空 assistant」在出网与读取两侧都拦住了,已实测确认:

  1. serialize_messages_anthropic / openai build_request 的 is_empty_assistant 过滤;
  2. SessionReader::load_messages 与 load_messages_with_orphan_results 的加载期过滤。

→ 不会污染线上请求,因此本单是 P3 而非 P2。

建议

两种方向,择一即可(建议 ①):

  1. 不落盘:handle_no_tool_calls 在 content 与 reasoning_content 均为空时
    不 push(与 #168 的 has_persistable_interrupt 判据保持一致的语义);
  2. 落盘但标记:保留行以便审计,明确标注其为「无内容终止」,
    并确保所有 serializer/loader 一致丢弃。

验收条件

  • 构造「模型返回 finish_reason=stop + 空 content + 无 tool_calls」的场景,
    断言 transcript 不含空的 assistant 行(或按方向 ② 断言其被一致丢弃);
  • 回归:cargo test --lib 0 failed;cargo test --test invariants 0 failed;
  • 若为 is_empty_assistant / has_persistable_interrupt 类判据,
    必须补断言或补等价性论证,不得使用 #[mutants::skip](#168 的既定纪律,
    已实测该门禁对本修复有效:撤销 skip 后变异可被杀死)。
主要言語
Rust
スター
4
フォーク
0
平均マージ
5時間 32分
マージ済み PR(30日)
7

環境構築

  • Dockerfile または Docker Compose ファイルあり
  • プルリクエストのテンプレートなし
  • コントリビューションガイドなし

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

jeffkit/recursive のほかの issue

jeffkit/recursive の issue をすべて見る

似ている issue

Rust の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。