PRODUCT NOTE / PRD

Quick Query Question

ページを閉じずに、その場で AI に訊く。
この文書は「どう使うか」ではなく、なぜ・誰のために・どんな判断で作ったかを記録した開発ノートです。

ステータスShipped / Active(v2.0.2)
初版2023-09-30(v0.5 系・ChatGPT 連携のポップアップ版)
刷新2026-07-18(v2.0.0・サイドパネル型へ全面刷新)
ストア公開2026-07-20(Chrome ウェブストアで公開)
提供形態Chrome 拡張機能(Manifest V3 / Chrome 116 以降)・限定公開
対象ユーザーGoogle 認証で許可されたユーザーのみ(許可リスト制)
最終更新2026-08-02
技術Manifest V3 ・ chrome.sidePanel ・ Google OAuth(id_token)→ 自前 JWT ・ FastAPI ・ Gemini 2.5 Flash ・ LangChain
関連リンクChrome ウェブストア開発ノート一覧
TL;DR

ひとことで

Quick Query Question は、ブラウザのサイドパネルに常駐する AI アシスタントです。閲覧中のページから離れずに、引用テキスト・画面キャプチャ・各種ファイル(PDF・画像・動画・CSV・テキスト等)を添えて質問・翻訳・校正・要約ができます。バックエンドは nzw.jp(Gemini)で、利用は許可制です。

Problem

背景・解きたい課題

v2.0.0 以前の動機は当時の設計文書が残っていないため、コミット履歴と実装から再構成した。v1 系の背景は推測

Who

ターゲットユーザー

プライマリ

運営者本人と、許可リストに登録された知人。Google 認証を通ったユーザーのみが利用でき、一般公開は前提にしていない。

主なユースケース

  • 読んでいる記事の一節を引用して要約・翻訳
  • 操作に迷った画面をキャプチャして「これは何?」
  • PDF や CSV を添付して中身を確認・整理
  • メールや資料の下書きを校正・敬語化
Solution & Scope

解決策とスコープ

コア機能(In scope)

  • サイドパネル常駐チャット(履歴保存・続きから再開)
  • ページのテキストを「引用する」ボタンで取り込み
  • 表示中の画面をキャプチャして添付
  • ファイル添付(PDF・画像・動画・CSV・テキスト・XML 等)とドラッグ&ドロップ
  • 長文入力の自動ファイル化
  • プロンプト登録(1〜50 個)とワンタップ挿入
  • Markdown 整形表示とワンクリックコピー

やらないこと(Non-goals)

  • 一般公開・誰でも使える AI サービス化
  • ページ内容の常時収集・バックグラウンド送信
  • Chrome 以外のブラウザ対応
  • 拡張内での独自 AI モデル保持
Success Metrics

成功指標(KPI)

「ページを離れずに完結したか」を中心に見る。数値は目標仮置き

0 回
別タブへの移動
(文脈が切れないか)
< 3 操作
選択から質問送信まで
(材料を渡す手間)
再利用率
登録プロンプトの利用
(定型指示が減るか)
Decision Log

主要な意思決定ログ

v2.0.1 以降の項目は実作業に基づく記録。v2.0.0 以前および security / UX の項目は、実装から読み取れる判断を再構成したもの。一部は実装から再構成

v2.0.2 「常に出す」に条件を一つ足す — 使えない相手にはボタンを出さない
DECISION
v2.0.1 で「引用ボタンはパネルの開閉に関わらず常に出す」と決めたが、未認証のときは設定に関わらず出さないという条件を足した。ログアウトした瞬間、すでに表示中のボタンも消す。判定は content script が保存済みユーザー情報の有効期限(exp)だけを見て行い、JWT 本体は読まない。認証状態が読み取れるまでは OFF 扱いにする。あわせて引用ボタンの表示 ON/OFF を設定画面に出した(即時反映)。
WHY / 仮説
この拡張は許可リスト制で、未ログインのままでは押しても何も起きない。押して無反応なボタンは「機能がある」ではなく「壊れている」と読まれる。加えて拡張はあらゆるページに注入されるため、権限のない相手にまで UI を撒くこと自体が無駄でもある。判定を content script 側で完結させたのは、ページごとに背景へ問い合わせる往復を避けるため。ただしページ側のコードに認証情報の中身を持ち込まないのは譲れないので、読むのは有効期限だけに絞った。読めない・判断がつかない状態は「出さない」側へ倒す(fail-closed)。
RESULT
未ログインおよびログアウト直後のページから引用ボタンが消えた。ログイン済みでも邪魔な場合は設定で切れるようになり、「常に出す」の押しつけも同時に解消した。
v2.0.2 入力欄は伸ばさず、最初から 5 行ぶん空けておく
DECISION
サイドパネルの入力欄を、常に 5 行分(116px)の高さで確保するようにした。CSS の min-height と JS 側の定数の両方に同じ値を持たせている。
WHY / 仮説
1 行から伸びる入力欄は短文の投稿を前提とした形だが、この拡張の主用途は「引用やファイルを添えて長めに指示する」ほう。書いている途中で欄が伸びるたびにレイアウトが動き、直前に書いた文が視界の外へ押し出される。最初から広く取っておけば、入力中に高さが変わらない。
RESULT
書き始めから 5 行が見える状態になり、入力中の高さ変化がなくなった。値を 2 箇所に持たせた点は重複であり、片方だけ変えると崩れる。次に触るときに一元化する。
v2.0.0 ポップアップを捨て、サイドパネル常駐にする
DECISION
v1 系のポップアップ UI を全面的に廃し、chrome.sidePanel による常駐パネルへ作り直した。同時に AI 基盤を ChatGPT 直叩きから nzw.jp(Gemini)経由へ移した。
WHY / 仮説
ポップアップは「ページをクリックすると閉じる」という仕様上、ページを見ながらの会話が原理的に成立しない。UI の改善では埋まらない構造的な問題だと判断した。バックエンドを自前に寄せたのは、API キーを拡張に埋め込まず許可制にできるため。
RESULT
ページを見ながら会話が続けられるようになり、会話履歴の保存・再開も自然に組み込めた。
UX 材料を渡す起点は「ページ側」に置く
DECISION
テキストを選択すると、その場に「引用する」ボタンを出す方式にした。パネル側から選択テキストを取りに行く方式は採らない。
WHY / 仮説
「選択 → パネルへ視線を移動 → ボタンを押す」より、「選択 → その場で押す」ほうが視線移動も操作数も少ない。ユーザーの意識がある場所に操作を置くべきだと考えた。
RESULT
引用は選択直後の 1 クリックで完了。のちに「範囲添付」ボタンと役割が重複していることが判明し、統廃合の判断につながった(下記)。
v2.0.1 重複していた「範囲添付」を捨て、ファイル添付に置き換える
DECISION
選択テキストを添付する「範囲添付」ボタンを廃止し、その枠をファイル添付に置き換えた。画像は既存の images 経路、それ以外は新設の files 経路(base64 + mime_type)で送る 2 系統に分けた。
WHY / 仮説
引用ボタンと範囲添付は「選択テキストを渡す」という同じ仕事をしており、ボタンが 2 つあること自体が迷いを生んでいた。機能を足すより先に、重複を消して枠を空けるべきだと判断した。経路を分けたのは、画像は送信前の縮小が必要で、他形式とは前処理が異なるため。
RESULT
操作の意味が「テキストは引用/実体のあるものは添付」と一意になった。PDF・動画・CSV 等は Gemini の inline データとして送られる。バックエンド反映待ち
UX 長文はユーザーに意識させず自動でファイル化する
DECISION
入力欄の内容が 2000 文字を超えた場合、送信時に自動で .txt の添付へ切り出す。
WHY / 仮説
長文をそのまま本文に載せると入力欄が読みにくくなる。かといって「長いので自分でファイルにしてください」と要求するのは本末転倒で、機械が判断できることは機械がやるべきだと考えた。
RESULT
ユーザーは長さを気にせず貼り付けられる。入力欄も添付一覧も見通しが保たれる。
v2.0.1 引用ボタンをパネル未起動でも押せるようにする
DECISION
従来はサイドパネルを開いている間しか引用ボタンを表示していなかったが、開閉に関わらず常に表示し、閉じている状態で押された場合はパネルを開いてから引用を挿入する方式に変えた。
WHY / 仮説
「引用したい」と思った瞬間にボタンが無いのは、機能が無いのと同じ。先にパネルを開かせるのは、こちらの都合をユーザーに押し付けている。
RESULT
実装上の落とし穴があった。chrome.sidePanel.open()ユーザー操作の直後にしか呼べないため、await を挟んでから呼ぶとジェスチャが失効して拒否される。引用テキストの保存より先に open() を呼ぶ順序が必須で、ここを崩すと機能が壊れる。
security API キーを拡張に持たせず、許可制の自前 JWT を挟む
DECISION
Google の id_token を nzw.jp のバックエンドで検証し、自前 JWT に交換して /v1/assistant/* を呼ぶ。許可リストに載ったメールアドレスのみ通す。
WHY / 仮説
拡張機能のコードはユーザーが閲覧できるため、AI の API キーを同梱すれば実質公開と同じになる。鍵はサーバー側にのみ置くべきだと判断した。
RESULT
鍵を露出させずに配布でき、利用者と利用量をサーバー側で制御できる。反面、ストアでは限定公開が前提になった。
privacy 権限は使わなくなった時点で削る
DECISION
範囲添付の廃止に伴い、選択テキスト取得のためだけに使っていた scripting 権限を manifest から削除した。
WHY / 仮説
使っていない権限が残っていると、審査で説明できないうえ、ユーザーに不要な不安を与える。権限は機能と一対一で増減させるべき。
RESULT
要求権限が 1 つ減り、機能と権限の対応が説明可能な状態に保たれた。
Architecture

構成メモ

拡張は 3 つのスクリプトに役割を分けている。ネットワーク通信は service worker に集約し、ページ側のスクリプトは最小限に留める。

構成要素役割
background.js(service worker)Google 認証(id_token → 自前 JWT の交換)と API 通信を集約。拡張の worker から fetch するため CORS を回避できる
sidepanel.jsチャット UI・履歴・プロンプト・入力欄制御。ファイルの読み込みと base64 化もここで行う
contents.js(content script)ページ上の「引用する」ボタンのみ。選択テキストを service worker へ渡す
受け渡し引用テキストは chrome.storage.local を仲介。パネルが開いていれば onChanged、閉じていれば起動時の読み込みで取り込む
バックエンドFastAPI の /v1/assistant/chat。添付は Gemini の inline データへ変換して送信
Milestones

これまでの歩み

v0.5 系2023-09-30

初版。ChatGPT 連携のポップアップ型ツールとして公開

v1.0 〜 v1.22023-10 〜 2024-01

入力上限の緩和、右クリックメニュー、コピー・テキスト書き出しなどを追加

v2.0.02026-07-18

サイドパネル型へ全面刷新。nzw.jp(Gemini)連携・Google 認証・会話履歴・プロンプト登録・引用ボタン・画面キャプチャ添付に対応

v2.0.12026-07-19

範囲添付を廃止しファイル添付(ドラッグ&ドロップ・長文の自動ファイル化)へ置換。引用ボタンをパネル未起動でも利用可能に。scripting 権限を削除

v2.0.22026-08-02

未認証時は引用ボタンを表示しない(判定は有効期限のみ・fail-closed)。引用ボタンの表示 ON/OFF を設定に追加。入力欄の高さを常時 5 行ぶん確保

Roadmap / Open Questions

これから

未決事項:添付データの保持方針、AI 利用コストの上限設計、公開範囲を広げるかどうか。