配置(重要:canonical な場所は移動済み)
2026 時点での canonical 実装は packages/analysis-core/src/analysis_core/steps/。8 ステップすべてここ。
2026-05-23 の legacy cleanup merge 後、apps/api/broadlistening/pipeline/ に旧 Python 実装は残っていない。current tree に残るのは sample configs/ / inputs/ だけで、実行コードとしての canonical path は analysis-core に一本化された。詳細は refactoring-status。
- エントリポイント(推奨):
python -m analysis_coreまたはkouchou-analyze(cli)
ステップ列
extraction— 生コメントから「意見」を LLM で抽出(コスト最大)embedding— 各意見を埋め込みベクトル化hierarchical_clustering— 階層クラスタリング(一層目/二層目)hierarchical_initial_labelling— 各クラスタに初期ラベルhierarchical_merge_labelling— 上位ラベル統合hierarchical_overview— 全体サマリhierarchical_aggregation— 集約レポート生成hierarchical_visualization— 散布図・ツリーマップ・dense-scatter 出力
実行モード
analysis_core.PipelineOrchestrator に 2 系統 ある:
run_default()/run_workflow()— current の canonical path。CLI と API サーバはここを使うrun()— direct-step fallback。互換性のため残るが deprecated で、canonical path ではない(refactoring-status)
利用者視点では、これは usage-modes にある CLI モード のコアにあたる。Web UI モードでも計算自体はこのパイプラインを共有するが、表示経路は public-viewer 側で分かれる。
LLM grouping 系 LLM 分類をどう差し込む想定だったか
slack-dev-kouchouai-2026-q1 2026-02-11 週では、近い将来の案として extraction, embedding の後に LLM ベースのクラスタリングへ分岐する枝 が語られている。これは理論上の最適形ではなく、まずは 既存のパイプラインや可視化と両立する形で分析切り替え部分を検証する ための互換性優先案。
同 source 2026-02-25 週では、embedding 後に分岐するのは「実装の楽さ」「後での可視化」のためであり、論理的に embedding が必須なわけではないとも整理されている。
要するに、近い枝は embedding を足場に使うが、長期的には分類基準そのものを距離空間から分類ツリーへ移す余地がある。
出力物の場所とスキーマ
{output_base_dir}/{report_id}/ 配下(CLI の --output-dir で指定。API サーバは settings.REPORT_DIR):
args.csv— 抽出された意見一覧(kebab-case 列:arg-id,comment-id等)embeddings.pkl— 元の埋め込みベクトル(UMAP 後 2D ではない)hierarchical_clusters.csv— クラスタ階層hierarchical_result.json— viewer が読む統合結果final_result_with_comments.csv—config.is_pubcom=trueのとき出力。この CSV だけ snake_case (arg_id,category_id) — 他は kebab-case (gotchas)
詳細スキーマは docs/development/plugin-output-data-structures.md。
主要な hidden assumption と落とし穴
- Slack では
embeddings.pklが UMAP 後 2D と誤認された形跡がある (slack-dev-kouchouai-2025-q4) が、main@3809a7aのコードではembeddingステップが元の埋め込みベクトルをembeddings.pklに保存し、hierarchical_clusteringステップがそれを読んでから UMAP で 2D に落としている(source-code) comment-idの自動採番が経路依存: Web CSV アップロードとスプレッドシート取り込みは自動生成するが、CLI/プラグイン/直接 CSV ではプラグイン側でcomment-idを出す責任があるpropertyMap(hierarchical_result.json):args.csvに対応する列がないとhierarchical_aggregationが落ちる- CSV 列名の case 不一致:
is_pubcom=true経路だけ snake_case - E2E パイプラインテストは課金: gpt-4o-mini で約 $0.01/run。
pyproject.tomlのnorecursedirs = ["tests/e2e"]で既定pytestから除外、CI でも実行されない
クラスタ数のデフォルト問題
meeting-minutes 2026-05-18 見出しで再浮上:docs/user-guide/cli-quickstart.md の例が [3, 6]。これを Claude Code がそのまま使い、300 件規模のデータでも 3 → 6 → 12 → 24 のような粗いまとめになる。
2026-05-18 の Issue #830 / PR #832 では、cluster_nums を optional にし、未指定時は extraction 後の argument 数から cube-root rule で自動算出する方向が具体化し、その後 merge された。argument_count=1000 なら [10, 100] を返し、small dataset 側も 2 -> [2], 3 -> [2, 3] へ補修されている。issue-830-pr-832-auto-cluster-defaults-2026-05-18より
過去にも kitaro が silhouette-score ベースの自動選択を PR #567 で実装したが embedding エラーの誘発で #579 で revert。今回の変更はその再試行ではなく、Admin 側に既にある単純な推奨値ルールを CLI / analysis-core に揃える修正 と理解する方が正確。issue-830-pr-832-auto-cluster-defaults-2026-05-18より
なぜ UMAP→クラスタリングなのか(既知の理論的弱点)
meeting-minutes 2025-10-08: 研究的には HDBSCAN を高次元で直接掛けるほうが精度が高いと知られているが、人間が高次元を見られない以上、散布図の可読性とのトレードオフで現状の構成を維持。代替を試したい場合は 解析 plugin として実装する方針。
加えて slack-kouchouai-algorithm-dev では、2025-05 から 2026-03 にかけて
- UMAP 軸に意味を読み込ませやすい
- 2D に落としてから
k-meansすると精度が落ちる - 同一トピック内の賛否が近くに置かれやすい
という批判が継続している。したがって現行構成は「理論的に妥当だと信じられている」のではなく、可視化都合を優先した暫定形 と読むべき。
書籍 13.2.4 (broad-listening-book-source) も同様に、UMAP→クラスタリング順を「機械学習の標準的な作法とは異なる選択であり、設計上の妥協を含んでいる」と明示している。出版可能形の確定版設計判断として外部に説明する際の引用元になる。同 13.5 では LLM コンテキストウィンドウ拡大を受けた 散布図タイプ vs Long Context タイプ の二アーキ比較が整理されており、pr-827-llm-grouping-capabilities-plan-2026-05-18 の analysis_mode 戦略と整合する。詳細は broad-listening-book-extractions。
軽量化と CLI 静的出力(2026-05)
meeting-minutes 2026-05-18 見出し / PR #825:
- 従来は「サーバを立てて
npm run build」する必要があったが、AI コーディングエージェントは「サーバ無しで HTML を出して静的ホスト」したい - Python から直接静的 HTML を吐く実装を追加。デフォルトをこちらにする方針
- 旧サーバ経路との見た目は 100% 同一ではない — 「実験的ビューを試しやすい」副産物がある
- ただし current プロダクトの主経路はなお
hierarchical_result.jsonをpublic-viewerで描画する形で、report.htmlは CLI 向け観察用HTMLとして理解する方が正確
PR #827 が何を具体化したか
pr-827-llm-grouping-capabilities-plan-2026-05-18 では、Slack 上で構想されていた 「embedding 後に LLM 分類を差し込む互換枝」 を、より具体的な移行計画として言語化している。
- 短期は
analysis_mode=llm_groupingを追加しつつembeddingを残し、x/yとcluster-level-*を従来フォーマットで出して viewer 互換を維持する - 長期は
analysis_capabilitiesを実データから自動導出し、可視化 mode の可否をrequirementsで判定する
これは「まず既存のパイプラインや可視化と両立する形で分析切り替えを試す」という slack-dev-kouchouai-2026-q1 の意図と整合する。一方で、この第 2 モードを LLM 直接グルーピングのもの と具体化して考えると、短期互換案そのものが「scatter-compatible な形へ一旦射影する暫定措置」にすぎないことも見えてくる。LLM grouping 系の本来の出力は tree / taxonomy / stance grouping であり、散布図は自然な主成果物ではない可能性が高い。したがって長期の本丸は mode 数を増やすことではなく、散布図を前提にしない analysis mode でも product が成立する capability contract を作ること である。2026-05-18 時点の main ではその production 実装は未着手と見るのが妥当。
Open Questions
extraction.skip: trueオプションの実装(複数回希望されているが未着地、議事メモ 2026-05-18 見出し時点)- レポート再利用(Issue #19)は 2026-02 に「実装し終わった」報告あり、現状確認が必要
- 散布図の維持/削除:「散布図を見て満足する時代ではない」(ken-san, 2025-10-01) vs nishio「少なくとも 2026-09 書籍版リリース時点までは温存し、より良い可視化が見つかれば併用→デフォルト切替も可」。未決(詳細は open-decisions A1)
- LLM grouping 系 LLM 分類を
embedding後の互換枝として入れるのか、embedding自体を省く独立 workflow にするのか
Updates
- 2026-05-17: 初回作成
- 2026-05-17:
#2_開発_広聴aiログ由来の LLM grouping 系 LLM 分類導入意図を追記 - 2026-05-17:
embeddings.pklを UMAP 後 2D とする記述を撤回し、Slack 発言とmain@3809a7aのコード実装を分離 - 2026-05-18: PR
#827を参照し、LLM grouping 系 LLM 分類の互換枝が plan PR として具体化したことを追記 - 2026-05-18:
#2_開発_広聴ai_アルゴリズム開発を source に追加し、UMAP→クラスタリングへの継続的批判を補足 - 2026-05-21: 書籍 13 章を broad-listening-book-source / broad-listening-book-extractions として ingest し、設計判断の出版可能形を相互リンク
- 2026-05-24:
work/kouchou-ai/main@e5ed743を確認し、旧apps/api/broadlistening/pipeline/実装削除後の current path に合わせて配置と実行モードの説明を更新 - 2026-05-25: 散布図維持側の nishio スタンスを「顧客がいる」から「2026-09 書籍版までは温存、より良い可視化があれば併用→切替も可」という時間軸ベースの表現に訂正