chore: 清理 docs 目录冗余文档(55个→9个)
删除: - docs/1.0/ 全部22个(旧Simple KB文档,已被替代) - docs/2.0/ 全部2个(空文件/过时) - docs/design/ 全部4个(旧功能设计) - docs/plans/ 旧版5个(保留v2.0设计文档) - docs/superpowers/ 全部4个(飞书集成文档) - docs/根目录杂项 8个(开发规范/快速参考/调试/飞书/Git设置) - docs/3.0/knowledge_graph_analysis.md(不相关) 保留: - docs/3.0/ 考核工作流设计 2个 - docs/plans/ v2.0设计文档 1个 - docs/tests/ 测试文档 6个 合计: 55个 → 9个 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -1,464 +0,0 @@
|
||||
# ナレッジベースの強化機能設計
|
||||
|
||||
## 🎯 機能概要
|
||||
|
||||
今回の開発には、以下の3つのコア機能が含まれます:
|
||||
|
||||
1. **ナレッジベースのグループ化** - グループを作成し、ドキュメントを複数のグループに所属させ、検索時にグループを指定可能にします。
|
||||
2. **検索履歴** - 対話プロセス全体を保存し、過去の会話の閲覧や再開を可能にします。
|
||||
3. **PDF プレビュー** - すべてのファイルを PDF 形式に変換し、オンラインでプレビューできるようにします。
|
||||
|
||||
## 🗄️ データベース設計
|
||||
|
||||
### 新規テーブル構造
|
||||
|
||||
```sql
|
||||
-- ナレッジベースグループ管理テーブル
|
||||
CREATE TABLE knowledge_groups (
|
||||
id TEXT PRIMARY KEY,
|
||||
name TEXT NOT NULL,
|
||||
description TEXT,
|
||||
color TEXT DEFAULT '#3B82F6', -- グループの色分けID
|
||||
user_id TEXT NOT NULL,
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- ドキュメント・グループ関連付けテーブル (多対多)
|
||||
CREATE TABLE knowledge_base_groups (
|
||||
knowledge_base_id TEXT NOT NULL,
|
||||
group_id TEXT NOT NULL,
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (knowledge_base_id, group_id),
|
||||
FOREIGN KEY (knowledge_base_id) REFERENCES knowledge_base(id) ON DELETE CASCADE,
|
||||
FOREIGN KEY (group_id) REFERENCES knowledge_groups(id) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
-- 検索履歴テーブル
|
||||
CREATE TABLE search_history (
|
||||
id TEXT PRIMARY KEY,
|
||||
user_id TEXT NOT NULL,
|
||||
title TEXT NOT NULL, -- 対話タイトル (質問の先頭50文字)
|
||||
selected_groups TEXT, -- JSON配列: ["group1", "group2"] または null(すべて)
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
-- 対話メッセージテーブル
|
||||
CREATE TABLE chat_messages (
|
||||
id TEXT PRIMARY KEY,
|
||||
search_history_id TEXT NOT NULL,
|
||||
role TEXT NOT NULL CHECK (role IN ('user', 'assistant')),
|
||||
content TEXT NOT NULL,
|
||||
sources TEXT, -- JSON配列: 引用ソース情報
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
FOREIGN KEY (search_history_id) REFERENCES search_history(id) ON DELETE CASCADE
|
||||
);
|
||||
```
|
||||
|
||||
### 既存テーブルの修正
|
||||
|
||||
```sql
|
||||
-- knowledge_base テーブルに PDF パスフィールドを追加
|
||||
ALTER TABLE knowledge_base ADD COLUMN pdf_path TEXT;
|
||||
```
|
||||
|
||||
## 🔌 API エンドポイント設計
|
||||
|
||||
### ナレッジベースグループ API
|
||||
|
||||
```typescript
|
||||
// ユーザーの全グループを取得
|
||||
GET /api/knowledge-groups
|
||||
Response: {
|
||||
groups: Array<{
|
||||
id: string;
|
||||
name: string;
|
||||
description?: string;
|
||||
color: string;
|
||||
fileCount: number; // 含まれるファイル数
|
||||
createdAt: string;
|
||||
}>
|
||||
}
|
||||
|
||||
// グループの作成
|
||||
POST /api/knowledge-groups
|
||||
Body: { name: string; description?: string; color?: string }
|
||||
Response: { id: string; name: string; description?: string; color: string }
|
||||
|
||||
// グループの更新
|
||||
PUT /api/knowledge-groups/:id
|
||||
Body: { name?: string; description?: string; color?: string }
|
||||
|
||||
// グループの削除
|
||||
DELETE /api/knowledge-groups/:id
|
||||
|
||||
// グループ内のファイルを取得
|
||||
GET /api/knowledge-groups/:id/files
|
||||
Response: { files: KnowledgeBase[] }
|
||||
|
||||
// ファイルをグループに追加
|
||||
POST /api/knowledge-bases/:fileId/groups
|
||||
Body: { groupIds: string[] }
|
||||
|
||||
// グループからファイルを削除
|
||||
DELETE /api/knowledge-bases/:fileId/groups/:groupId
|
||||
```
|
||||
|
||||
### 検索履歴 API
|
||||
|
||||
```typescript
|
||||
// 検索履歴の取得 (ページネーション)
|
||||
GET /api/search-history?page=1&limit=20
|
||||
Response: {
|
||||
histories: Array<{
|
||||
id: string;
|
||||
title: string;
|
||||
selectedGroups: string[] | null;
|
||||
messageCount: number;
|
||||
lastMessageAt: string;
|
||||
createdAt: string;
|
||||
}>;
|
||||
total: number;
|
||||
page: number;
|
||||
limit: number;
|
||||
}
|
||||
|
||||
// 対話詳細の取得
|
||||
GET /api/search-history/:id
|
||||
Response: {
|
||||
id: string;
|
||||
title: string;
|
||||
selectedGroups: string[] | null;
|
||||
messages: Array<{
|
||||
id: string;
|
||||
role: 'user' | 'assistant';
|
||||
content: string;
|
||||
sources?: Array<{
|
||||
fileName: string;
|
||||
content: string;
|
||||
score: number;
|
||||
chunkIndex: number;
|
||||
}>;
|
||||
createdAt: string;
|
||||
}>;
|
||||
}
|
||||
|
||||
// 新しい対話の作成
|
||||
POST /api/search-history
|
||||
Body: {
|
||||
title: string;
|
||||
selectedGroups?: string[];
|
||||
firstMessage: string;
|
||||
}
|
||||
Response: { id: string }
|
||||
|
||||
// 対話の削除
|
||||
DELETE /api/search-history/:id
|
||||
|
||||
// 対話の継続 (既存のチャットインターフェースを拡張し、historyId パラメータを追加)
|
||||
POST /api/chat/stream
|
||||
Body: {
|
||||
message: string;
|
||||
history: ChatMessage[];
|
||||
userLanguage?: string;
|
||||
selectedGroups?: string[]; // 新規:選択されたグループ
|
||||
historyId?: string; // 新規:対話履歴ID
|
||||
}
|
||||
```
|
||||
|
||||
### PDF プレビュー API
|
||||
|
||||
```typescript
|
||||
// ファイルの PDF プレビューを取得
|
||||
GET /api/knowledge-bases/:id/pdf
|
||||
Response: PDF ファイルストリーム、または PDF URL へのリダイレクト
|
||||
|
||||
// PDF ステータスの確認
|
||||
GET /api/knowledge-bases/:id/pdf-status
|
||||
Response: {
|
||||
status: 'pending' | 'converting' | 'ready' | 'failed';
|
||||
pdfPath?: string;
|
||||
error?: string;
|
||||
}
|
||||
```
|
||||
|
||||
## 🎨 フロントエンドコンポーネント設計
|
||||
|
||||
### 1. ナレッジベースグループコンポーネント
|
||||
|
||||
```typescript
|
||||
// グループマネージャー
|
||||
interface GroupManagerProps {
|
||||
groups: KnowledgeGroup[];
|
||||
onCreateGroup: (group: CreateGroupData) => void;
|
||||
onUpdateGroup: (id: string, data: UpdateGroupData) => void;
|
||||
onDeleteGroup: (id: string) => void;
|
||||
}
|
||||
|
||||
// グループセレクター (検索時の選択用)
|
||||
interface GroupSelectorProps {
|
||||
groups: KnowledgeGroup[];
|
||||
selectedGroups: string[];
|
||||
onSelectionChange: (groupIds: string[]) => void;
|
||||
showSelectAll?: boolean;
|
||||
}
|
||||
|
||||
// ファイルグループタグ
|
||||
interface FileGroupTagsProps {
|
||||
fileId: string;
|
||||
groups: KnowledgeGroup[];
|
||||
assignedGroups: string[];
|
||||
onGroupsChange: (groupIds: string[]) => void;
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 検索履歴コンポーネント
|
||||
|
||||
```typescript
|
||||
// 履歴リスト
|
||||
interface SearchHistoryListProps {
|
||||
histories: SearchHistoryItem[];
|
||||
onSelectHistory: (historyId: string) => void;
|
||||
onDeleteHistory: (historyId: string) => void;
|
||||
onLoadMore: () => void;
|
||||
hasMore: boolean;
|
||||
}
|
||||
|
||||
// 履歴対話ビューアー
|
||||
interface HistoryViewerProps {
|
||||
historyId: string;
|
||||
onContinueChat: (historyId: string) => void;
|
||||
onClose: () => void;
|
||||
}
|
||||
```
|
||||
|
||||
### 3. PDF プレビューコンポーネント
|
||||
|
||||
```typescript
|
||||
// PDF プレビューアー
|
||||
interface PDFPreviewProps {
|
||||
fileId: string;
|
||||
fileName: string;
|
||||
onClose: () => void;
|
||||
}
|
||||
|
||||
// PDF プレビューボタン
|
||||
interface PDFPreviewButtonProps {
|
||||
fileId: string;
|
||||
fileName: string;
|
||||
status: 'pending' | 'converting' | 'ready' | 'failed';
|
||||
}
|
||||
```
|
||||
|
||||
## 🔄 ビジネスフロー設計
|
||||
|
||||
### ナレッジベースグループ化フロー
|
||||
|
||||
```
|
||||
1. ユーザーがグループを作成 → knowledge_groups テーブルに保存
|
||||
2. ファイルアップロード時 → グループを選択可能 → knowledge_base_groups テーブルに関連付けを保存
|
||||
3. 検索時 → グループを選択 → Elasticsearch のクエリ範囲をフィルタリング
|
||||
4. ファイル管理 → ファイルの所属グループを編集可能
|
||||
```
|
||||
|
||||
### 検索履歴フロー
|
||||
|
||||
```
|
||||
1. ユーザーがチャットを開始 → search_history データを生成
|
||||
2. 各メッセージ → chat_messages テーブルに保存
|
||||
3. 履歴の確認 → 履歴リストをページネーションでロード
|
||||
4. 履歴をクリック → 対話内容全体をロード
|
||||
5. 対話の継続 → 既存の履歴をベースに新しいメッセージを追加
|
||||
```
|
||||
|
||||
### PDF プレビューフロー
|
||||
|
||||
```
|
||||
1. ファイルアップロード → PDF かどうかを確認
|
||||
2. PDF 以外の場合 → LibreOffice を呼び出して PDF に変換
|
||||
3. PDF パスを knowledge_base.pdf_path に保存
|
||||
4. フロントエンドからプレビューをリクエスト → PDF ファイルストリームを返却
|
||||
5. HTML の <embed> または <iframe> を使用して PDF を表示
|
||||
```
|
||||
|
||||
## 🛠️ 技術実装のポイント
|
||||
|
||||
### 1. ES クエリ最適化 (グループフィルタリング)
|
||||
|
||||
```typescript
|
||||
// ElasticsearchService.hybridSearch を修正
|
||||
async hybridSearch(
|
||||
queryVector: number[],
|
||||
queryText: string,
|
||||
userId: string,
|
||||
topK: number = 10,
|
||||
threshold: number = 0.6,
|
||||
selectedGroups?: string[] // 新規パラメータ
|
||||
): Promise<any[]> {
|
||||
|
||||
// グループフィルタリング条件を構築
|
||||
const groupFilter = selectedGroups?.length
|
||||
? { terms: { "knowledge_base_id": await this.getFileIdsByGroups(selectedGroups, userId) } }
|
||||
: undefined;
|
||||
|
||||
// ES クエリにフィルタ条件を追加
|
||||
const query = {
|
||||
bool: {
|
||||
must: [/* 既存のクエリ条件 */],
|
||||
filter: [
|
||||
{ term: { user_id: userId } },
|
||||
...(groupFilter ? [groupFilter] : [])
|
||||
]
|
||||
}
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
### 2. PDF 変換サービスの統合
|
||||
|
||||
```typescript
|
||||
// KnowledgeBaseService に PDF 変換を追加
|
||||
async ensurePDFExists(kb: KnowledgeBase): Promise<string> {
|
||||
if (kb.pdfPath && await fs.pathExists(kb.pdfPath)) {
|
||||
return kb.pdfPath;
|
||||
}
|
||||
|
||||
if (kb.mimetype === 'application/pdf') {
|
||||
// 既に PDF なので、元のファイルをそのまま使用
|
||||
kb.pdfPath = kb.storagePath;
|
||||
} else {
|
||||
// LibreOffice を呼び出して変換
|
||||
const pdfPath = await this.libreOfficeService.convertToPDF(kb.storagePath);
|
||||
kb.pdfPath = pdfPath;
|
||||
}
|
||||
|
||||
await this.knowledgeBaseRepository.save(kb);
|
||||
return kb.pdfPath;
|
||||
}
|
||||
```
|
||||
|
||||
### 3. チャット履歴の保存
|
||||
|
||||
```typescript
|
||||
// ChatService.streamChat メソッドを修正
|
||||
async *streamChat(
|
||||
message: string,
|
||||
history: ChatMessage[],
|
||||
userId: string,
|
||||
modelConfig: ModelConfig,
|
||||
userLanguage: string = 'zh',
|
||||
selectedEmbeddingId?: string,
|
||||
selectedGroups?: string[], // 新規
|
||||
historyId?: string // 新規
|
||||
): AsyncGenerator<{ type: 'content' | 'sources'; data: any }> {
|
||||
|
||||
// historyId がない場合は、新しい対話履歴を作成
|
||||
if (!historyId) {
|
||||
historyId = await this.createSearchHistory(userId, message, selectedGroups);
|
||||
}
|
||||
|
||||
// ユーザーメッセージを保存
|
||||
await this.saveChatMessage(historyId, 'user', message);
|
||||
|
||||
// ... 既存のロジック ...
|
||||
|
||||
// AI の回答を保存
|
||||
await this.saveChatMessage(historyId, 'assistant', fullResponse, sources);
|
||||
}
|
||||
```
|
||||
|
||||
## 📱 UI/UX 設計のポイント
|
||||
|
||||
### 1. グループ管理インターフェース
|
||||
|
||||
- サイドバーにグループリストを表示
|
||||
- グループへのファイルのドラッグ&ドロップに対応
|
||||
- グループの色分け表示
|
||||
- グループ内のファイル数を表示
|
||||
|
||||
### 2. 検索インターフェースの強化
|
||||
|
||||
- チャット入力欄の上にグループセレクターを追加
|
||||
- 複数グループの選択と状態表示に対応
|
||||
- 「全グループ」オプション
|
||||
|
||||
### 3. 履歴管理インターフェース
|
||||
|
||||
- 左側に履歴リスト、右側に対話内容を表示
|
||||
- 履歴にはタイトル、時間、メッセージ数を表示
|
||||
- 履歴の削除と対話の再開をサポート
|
||||
|
||||
### 4. PDF プレビュー
|
||||
|
||||
- モーダル形式で PDF を表示
|
||||
- フルスクリーン表示をサポート
|
||||
- 読み込み状態の表示とエラー処理
|
||||
|
||||
## 🚀 開発計画
|
||||
|
||||
### ✅ フェーズ1: データベースとバックエンド API (完了)
|
||||
|
||||
1. ✅ データベースのマイグレーションスクリプト
|
||||
2. ✅ グループ管理 API
|
||||
3. ✅ 履歴管理 API
|
||||
4. ✅ PDF プレビュー API
|
||||
5. ✅ チャットサービスの強化 (グループフィルタリングと履歴保存)
|
||||
6. ✅ Elasticsearch のグループフィルタリング機能
|
||||
|
||||
### 🔄 フェーズ2: フロントエンドコンポーネント開発 (進行中)
|
||||
|
||||
1. ⏳ グループ管理コンポーネント (基本機能は実装済み。アクセス方法を最適化予定)
|
||||
2. ⏳ 履歴管理コンポーネント (基本機能は実装済み)
|
||||
3. ⏳ PDF プレビューコンポーネント (基本機能は実装済み)
|
||||
4. ✅ **UI の刷新と設定の統合**: ヘッダーとサイドバーを整理し、設定の入り口を統一。新機能のためのスペースを確保。
|
||||
|
||||
### ⏳ フェーズ3: 統合とテスト (待機中)
|
||||
|
||||
1. ⏳ 機能の統合
|
||||
2. ⏳ エンドツーエンド (E2E) テスト
|
||||
3. ⏳ パフォーマンスの最適化
|
||||
|
||||
---
|
||||
|
||||
## ✅ 完了済みのバックエンド開発
|
||||
|
||||
### データベース設計
|
||||
|
||||
- ✅ 4つの新しいテーブルを作成:`knowledge_groups`、`knowledge_base_groups`、`search_history`、`chat_messages`
|
||||
- ✅ `knowledge_base` テーブルに `pdf_path` フィールドを追加
|
||||
- ✅ 完全なデータベースマイグレーションスクリプトを作成
|
||||
|
||||
### エンティティとサービス
|
||||
|
||||
- ✅ `KnowledgeGroup` エンティティとサービス (多対多関係をサポート)
|
||||
- ✅ `SearchHistory` および `ChatMessage` エンティティとサービス
|
||||
- ✅ `KnowledgeBase` エンティティを更新し、グループ関係と PDF パスを追加
|
||||
|
||||
### API エンドポイント
|
||||
|
||||
- ✅ ナレッジベースグループ管理 : `GET/POST/PUT/DELETE /api/knowledge-groups`
|
||||
- ✅ ファイル・グループ関連付け : `POST/DELETE /api/knowledge-bases/:id/groups`
|
||||
- ✅ 検索履歴管理 : `GET/POST/DELETE /api/search-history`
|
||||
- ✅ PDF プレビュー : `GET /api/knowledge-bases/:id/pdf` および `GET /api/knowledge-bases/:id/pdf-status`
|
||||
|
||||
### チャット機能の強化
|
||||
|
||||
- ✅ グループフィルタリング検索をサポート (`selectedGroups` パラメータ)
|
||||
- ✅ 対話履歴の自動生成と保存
|
||||
- ✅ 対話の再開をサポート (`historyId` パラメータ)
|
||||
- ✅ Elasticsearch によるグループフィルタリングクエリ
|
||||
|
||||
### テストと検証
|
||||
|
||||
- ✅ 自動テストスクリプト `test-enhancements.sh` を作成
|
||||
- ✅ すべての API エンドポイントが実装され、テスト可能
|
||||
|
||||
**バックエンド開発ステータス**: ✅ **完了** (約 95%)
|
||||
|
||||
**次のステップ**: フロントエンドコンポーネントの開発を開始
|
||||
|
||||
---
|
||||
|
||||
**予想開発期間**: 5〜8日
|
||||
**優先度**: グループ化機能 > PDF プレビュー > 履歴管理
|
||||
Reference in New Issue
Block a user