purpose
search に vector_ids パラメータを追加し、索引が既に保持している本文を取り出せるようにする。現在 doc / wiki_doc 以外の型には本文を返す手段が一切なく、search であたりを付けたあと gh や grep で取り直す一往復が必要になっている。普段使いの retrieval コストの問題である。
過去の判断(先に確認済み)
専用 tool を追加する案を検討し、退けた。#104 / #105 で 4 tool を search 1 本へ統合した判断があり、専用 tool はその逆行になる。
削除された 3 tool: get_issue_context / get_doc_content / list_recent_activity。本文取得の専用 tool は get_doc_content の復活そのものである。
統合時の設計意図(commit 6acdbd3 body より):
search_issues now exposes three modes via its parameter set: hybrid semantic search (existing), time-ordered activity scan (empty query + sort=updated_desc/created_desc + optional since/until), and inline doc content fetch (include_content).
「パラメータ集合でモードを表現する」形は意図された設計であり、事故ではない。したがって本 issue もその作法に乗る。
なお #104 は起票者アカウントの凍結により GitHub 上で参照できない(gh issue view 104 は 404)。上記の意図はローカル clone の commit body から復元した。commit body に意図を書く規約が、issue が読めなくなっても判断を保存していた事例である。
premise
本文は既に読み込まれていて、返す直前に捨てられている
src/mcp.ts の search 経路は reranker に食わせるために D1 FTS 行の content を読み込む(L773-820)。dense 側だけでヒットした候補には search_docs からのバックフィルまで行う(L788-806)。つまり結果組み立て時点で content はメモリ上にある。
しかし出力に載るのは doc / wiki_doc だけ。inlineDocContent(L1222)が対象を絞っており、非 doc 行は素通りする(tool description L429: "Non-doc rows are unaffected")。
対照的に graph 軸の buildGraphItem(L258)は includeContent で row.content を型を問わずそのまま返している。同じ include_content フラグで keyword 軸と graph 軸の挙動が割れている。
索引が保持している content の実体
全 surface が FTS に書いているのは embedding input そのもの。
| surface |
書き込み箇所 |
中身 |
| issue / PR |
embed-issue.ts L190, L285 |
prepareEmbeddingInput(title, body) |
| comment / review |
embed-comment.ts L134, L247, L372 |
embedding input |
| release |
embed-release.ts L125 |
embedding input |
| doc / wiki_doc |
embed-doc.ts L82, L186 |
embedding input |
| diff |
embed-diff.ts L249 |
embedding input |
いずれも MAX_EMBEDDING_INPUT_CHARS = 8000 で truncate されている。索引に尾は存在しない。
実測(Liplus-Project/liplus-language の issue body 10 件): 1,175 / 1,319 / 1,400 / 1,640 / 1,749 / 1,975 / 2,226 / 2,715 / 3,193 / 3,696 文字。8000 超は 0 件。issue 本文では上限がほぼ効かない。一方 diff 行は patch なので日常的に上限に当たる。
doc 経路が GitHub から取り直している理由
embed-doc.ts も content を D1 に持っているのに、include_content は contents API を叩いている。これは冗長ではなく、doc は完全なファイルが必要で 8000 文字の頭では足りないため。INCLUDE_CONTENT_MAX_DOCS = 5 はその API fan-out を抑える上限である。
したがって include_content と本 issue の経路を統合してはならない。取得元と上限の根拠が違う。
設計
既存の導出作法に合わせる。モードは列挙パラメータで選ばせず、パラメータ集合から導出する。
query が空 -> scan (既存、L481 の isScanMode)
include_content -> doc 本文 inline(既存、contents API 経由)
vector_ids が存在 -> 本文取得 (本 issue)
vector_ids が渡されたら、その行の保存済み content を返す。呼び出し側が対象を名指しするため、サーバ側が合計バイト数上限を発明する必要がない。フラグ方式で必要になる「どこまで返せば安全かの推測」がここでは発生しない。
vector_id は search の結果各行に追加する。内部では既に主キー(L663 の vector_id -> payload lookup)。
ただし永続識別子として約束しない。 この repo には legacy vector id の移行履歴(src/pipeline/legacy-vector-id.ts、pre-migration generation)がある。「検索結果からその場で引くための一時的な取っ手」として description に明記し、採番変更で縛られない形にする。
応答の mode フィールドが現在 "search" / "scan" の 2 値であるため、本経路をどう報告するかは実装判断。
constraints
target files
src/mcp.ts — vector_ids パラメータ、search 結果への vector_id 追加、tool description
docs/0-requirements.md / docs/0-requirements.ja.md — MCP Tool Surface 節
- テスト — 型ごとに content が返ること、未知
vector_id の部分成功、truncate 表示、search 結果に vector_id が載ること
acceptance
search の結果各行に vector_id が載る
vector_ids を渡すと issue / pull_request / issue_comment / pr_review / pr_review_comment / release / diff の本文が返る
- GitHub API 呼び出し数が増えていない
- 索引由来・truncate 済みであることが結果から判別できる
- 未知の
vector_id が混ざっても残りは返る
include_content の既存挙動が変わっていない
- MCP tool 数が 1 のまま
補足(この issue のスコープ外)
保存済み content が embedding input と同一値であるため、8000 文字上限は embedding のための判断が保存の判断を兼ねている状態にある。FTS 側に truncate しない本文を持たせるのが根本の形だが、既存行の再 index が必要で、範囲が別。ここでは「既に持っているものを返す」に限定する。
purpose
searchにvector_idsパラメータを追加し、索引が既に保持している本文を取り出せるようにする。現在doc/wiki_doc以外の型には本文を返す手段が一切なく、searchであたりを付けたあとghや grep で取り直す一往復が必要になっている。普段使いの retrieval コストの問題である。過去の判断(先に確認済み)
専用 tool を追加する案を検討し、退けた。#104 / #105 で 4 tool を
search1 本へ統合した判断があり、専用 tool はその逆行になる。削除された 3 tool:
get_issue_context/get_doc_content/list_recent_activity。本文取得の専用 tool はget_doc_contentの復活そのものである。統合時の設計意図(commit
6acdbd3body より):「パラメータ集合でモードを表現する」形は意図された設計であり、事故ではない。したがって本 issue もその作法に乗る。
なお #104 は起票者アカウントの凍結により GitHub 上で参照できない(
gh issue view 104は 404)。上記の意図はローカル clone の commit body から復元した。commit body に意図を書く規約が、issue が読めなくなっても判断を保存していた事例である。premise
本文は既に読み込まれていて、返す直前に捨てられている
src/mcp.tsの search 経路は reranker に食わせるために D1 FTS 行のcontentを読み込む(L773-820)。dense 側だけでヒットした候補にはsearch_docsからのバックフィルまで行う(L788-806)。つまり結果組み立て時点で content はメモリ上にある。しかし出力に載るのは
doc/wiki_docだけ。inlineDocContent(L1222)が対象を絞っており、非 doc 行は素通りする(tool description L429: "Non-doc rows are unaffected")。対照的に graph 軸の
buildGraphItem(L258)はincludeContentでrow.contentを型を問わずそのまま返している。同じinclude_contentフラグで keyword 軸と graph 軸の挙動が割れている。索引が保持している content の実体
全 surface が FTS に書いているのは embedding input そのもの。
embed-issue.tsL190, L285prepareEmbeddingInput(title, body)embed-comment.tsL134, L247, L372embed-release.tsL125embed-doc.tsL82, L186embed-diff.tsL249いずれも
MAX_EMBEDDING_INPUT_CHARS = 8000で truncate されている。索引に尾は存在しない。実測(
Liplus-Project/liplus-languageの issue body 10 件): 1,175 / 1,319 / 1,400 / 1,640 / 1,749 / 1,975 / 2,226 / 2,715 / 3,193 / 3,696 文字。8000 超は 0 件。issue 本文では上限がほぼ効かない。一方diff行は patch なので日常的に上限に当たる。doc 経路が GitHub から取り直している理由
embed-doc.tsも content を D1 に持っているのに、include_contentは contents API を叩いている。これは冗長ではなく、doc は完全なファイルが必要で 8000 文字の頭では足りないため。INCLUDE_CONTENT_MAX_DOCS = 5はその API fan-out を抑える上限である。したがって
include_contentと本 issue の経路を統合してはならない。取得元と上限の根拠が違う。設計
既存の導出作法に合わせる。モードは列挙パラメータで選ばせず、パラメータ集合から導出する。
vector_idsが渡されたら、その行の保存済み content を返す。呼び出し側が対象を名指しするため、サーバ側が合計バイト数上限を発明する必要がない。フラグ方式で必要になる「どこまで返せば安全かの推測」がここでは発生しない。vector_idはsearchの結果各行に追加する。内部では既に主キー(L663 のvector_id -> payloadlookup)。ただし永続識別子として約束しない。 この repo には legacy vector id の移行履歴(
src/pipeline/legacy-vector-id.ts、pre-migration generation)がある。「検索結果からその場で引くための一時的な取っ手」として description に明記し、採番変更で縛られない形にする。応答の
modeフィールドが現在"search"/"scan"の 2 値であるため、本経路をどう報告するかは実装判断。constraints
vector_idは一時的な取っ手として扱う。永続性を description で約束しないdoc/wiki_docのinclude_content既存挙動(contents API から完全なファイル、5 件上限)は変更しないvector_idは部分成功として扱う。1 件の失敗で全体を落とさないdocs/0-requirements.md/docs/0-requirements.ja.md)を同一 PR で更新するtarget files
src/mcp.ts—vector_idsパラメータ、search結果へのvector_id追加、tool descriptiondocs/0-requirements.md/docs/0-requirements.ja.md— MCP Tool Surface 節vector_idの部分成功、truncate 表示、search結果にvector_idが載ることacceptance
searchの結果各行にvector_idが載るvector_idsを渡すとissue/pull_request/issue_comment/pr_review/pr_review_comment/release/diffの本文が返るvector_idが混ざっても残りは返るinclude_contentの既存挙動が変わっていない補足(この issue のスコープ外)
保存済み content が embedding input と同一値であるため、8000 文字上限は embedding のための判断が保存の判断を兼ねている状態にある。FTS 側に truncate しない本文を持たせるのが根本の形だが、既存行の再 index が必要で、範囲が別。ここでは「既に持っているものを返す」に限定する。