1 line
21 KiB
JSON
1 line
21 KiB
JSON
{"repo": "actbit/chatterbot", "files": {"README.md": {"be9ff9e3644ecdcb0c443c724f4efd66b51c201a": {"t": 1785674179.1084726, "n": 14308, "h": "481cd897c09b54c4", "c": "<div align=\"center\">\n\n# 🤖 ChatterBot\n\n**Discordで自然に会話に参加する、ちょっと便利なチャット仲間**\n\n[](https://dotnet.microsoft.com/)\n[](https://github.com/RogueException/Discord.Net)\n[](https://github.com/microsoft/semantic-kernel)\n[](LICENSE)\n\n[English](#english) | **日本語**\n\n</div>\n\n---\n\n## ✨ 何ができる?\n\nChatterBot は普通のチャットボットとは違います。\n\n- 🎭 **自然な会話参加** - メンションされなくても、面白そうな話題には横入り\n- 🧠 **文脈を理解** - 誰が何を言ったか把握して、会話の流れを読む\n- 🔍 **長期記憶** - 先週の話題も検索して「あれどうなった?」に答える\n- 🛠️ **便利な機能** - 計算、サイコロ、日付計算、URL要約、画像認識...\n- 🌐 **マルチモデル対応** - OpenAI、GLM、その他のOpenAI互換API\n\n> 「計算してみるね」→ `56088だった` みたいに、自然に機能を使う感じ\n\n---\n\n## 📋 目次\n\n- [デモ](#-デモ)\n- [特徴](#-特徴)\n- [クイックスタート](#-クイックスタート)\n- [設定](#%EF%B8%8F-設定)\n- [機能一覧](#-機能一覧)\n- [アーキテクチャ](#-アーキテクチャ)\n- [カスタマイズ](#%EF%B8%8F-カスタマイズ)\n- [開発](#-開発)\n- [コントリビュート](#-コントリビュート)\n\n---\n\n## 🎬 デモ\n\n### 自然な会話への参加\n\n```\n👤 田中: 今日ラーメン食べた\n👤 佐藤: 美味しかった?\n👤 田中: うま!二郎系だった\n🤖 ChatterBot: 二郎か!濃いな〜、帰り眠くならなかった?🍜\n```\n\n### 計算・日付機能\n\n```\n👤 ユーザー: 123 * 456っていくつ?\n🤖 ChatterBot: ちょっと計算するね\n🤖 ChatterBot: 56088だった\n\n👤 ユーザー: クリスマスまであと何日?\n🤖 ChatterBot: 312日あるよ。まだ早いね🎄\n```\n\n### 過去の話題を検索\n\n```\n👤 ユーザー: 先週何の話してたっけ?\n🤖 ChatterBot: うーん、思い出してみる...\n🤖 ChatterBot: アニメの話してたね。推しの子の話が盛り上がってた\n```\n\n---\n\n## 🌟 特徴\n\n<table>\n<tr>\n<td width=\"50%\">\n\n### 🎯 自律的な返信判断\n\nAIが自ら「返信するかどうか」を判断。\n\n- 面白い話題 → 横入り\n- 質問されてる → 答える\n- 特に言うことない → 見てるだけ\n\n</td>\n<td width=\"50%\">\n\n### 🧠 ハイブリッド履歴管理\n\n2層構造で会話を記憶:\n\n- **ChatHistory** - 直近N日分(コンテキスト維持)\n- **RAG検索** - 全期間(意味的検索)\n\n</td>\n</tr>\n<tr>\n<td width=\"50%\">\n\n### 🌐 OpenAI互換API\n\n様々なAIモデルを使用可能:\n\n- OpenAI GPT-4o / GPT-4\n- GLM (ZhipuAI)\n- Azure OpenAI\n- その他OpenAI互換API\n\n</td>\n<td width=\"50%\">\n\n### 🏠 サーバー分離\n\n- 異なるサーバーの履歴は完全分離\n- DMにも対応\n- チャンネルごとに独立した会話\n\n</td>\n</tr>\n</table>\n\n---\n\n## 🚀 クイックスタート\n\n### 前提条件\n\n- [.NET 10.0 SDK](https://dotnet.microsoft.com/download)\n- Discord Bot Token ([取得方法](https://discord.com/developers/applications))\n- OpenAI API Key または互換API\n\n### 1. クローン\n\n```bash\ngit clone https://github.com/yourusername/ChatterBot.git\ncd ChatterBot\n```\n\n### 2. 環境変数設定\n\n```bash\n# Linux/macOS\nexport DISCORD_BOT_TOKEN=\"your_discord_token\"\nexport OPENAI_API_KEY=\"your_api_key\"\nexport OPENAI_MODEL_ID=\"gpt-4o\"\n\n# Windows PowerShell\n$env:DISCORD_BOT_TOKEN=\"your_discord_token\"\n$env:OPENAI_API_KEY=\"your_api_key\"\n$env:OPENAI_MODEL_ID=\"gpt-4o\"\n```\n\n### 3. 実行\n\n```bash\ncd ChatterBot\ndotnet run\n```\n\n### 🐳 Docker で実行\n\n```bash\ndocker build -t chatterbot .\ndocker run -d \\\n -e DISCORD_BOT_TOKEN=your_token \\\n -e OPENAI_API_KEY=your_key \\\n -e OPENAI_MODEL_ID=gpt-4o \\\n -v chatterbot-data:/app/data \\\n chatterbot\n```\n\n---\n\n## ⚙️ 設定\n\n### 環境変数一覧\n\n| 変数名 | 必須 | 説明 | 例 |\n|--------|:----:|------|-----|\n| `DISCORD_BOT_TOKEN` | ✅ | Discord Bot Token | `MTk4Nj...` |\n| `OPENAI_MODEL_ID` | ✅ | 使用するモデル | `gpt-4o` |\n| `OPENAI_API_KEY` | ✅ | API Key | `sk-...` |\n| `OPENAI_ENDPOINT` | | カスタムエンドポイント | `https://open.bigmodel.cn/api/paas/v4/` |\n| `EMBEDDING_PROVIDER` | | Embeddingプロバイダー | `openai`, `glm`, `none` |\n| `EMBEDDING_MODEL_ID` | | Embeddingモデル | `text-embedding-3-small` |\n| `EMBEDDING_API_KEY` | | Embedding用API Key | |\n| `Vision__SupportsVision` | | Vision対応フラグ | `true`, `false` |\n| `VISION_MODEL_ID` | | 画像認識モデル | `gpt-4o` |\n| `VISION_API_KEY` | | 画像認識用API Key | |\n| `VISION_ENDPOINT` | | 画像認識エンドポイント | |\n\n### appsettings.json での設定\n\n環境変数のプレースホルダーを使用:\n\n```json\n{\n \"Discord\": {\n \"Token\": \"${DISCORD_BOT_TOKEN}\"\n },\n \"OpenAI\": {\n \"ModelId\": \"${OPENAI_MODEL_ID}\",\n \"ApiKey\": \"${OPENAI_API_KEY}\",\n \"Endpoint\": \"${OPENAI_ENDPOINT}\"\n },\n \"Vision\": {\n \"SupportsVision\": false,\n \"ModelId\": \"${VISION_MODEL_ID}\",\n \"ApiKey\": \"${VISION_API_KEY}\",\n \"Endpoint\": \"${VISION_ENDPOINT}\"\n },\n \"Embedding\": {\n \"Provider\": \"${EMBEDDING_PROVIDER}\",\n \"ModelId\": \"${EMBEDDING_MODEL_ID}\",\n \"ApiKey\": \"${EMBEDDING_API_KEY}\",\n \"Endpoint\": \"${EMBEDDING_ENDPOINT}\"\n },\n \"Database\": {\n \"Path\": \"data/chatterbot.db\"\n },\n \"History\": {\n \"ChatHistoryMaxMessages\": 30,\n \"RagSearchLimit\": 5,\n \"DefaultLoadDays\": 7\n }\n}\n```\n\n### GLM (ZhipuAI) を使用する場合\n\n```bash\nexport OPENAI_MODEL_ID=\"glm-4-plus\"\nexport OPENAI_API_KEY=\"your_glm_api_key\"\nexport OPENAI_ENDPOINT=\"https://open.bigmodel.cn/api/paas/v4/\"\n\nexport EMBEDDING_PROVIDER=\"glm\"\nexport EMBEDDING_MODEL_ID=\"embedding-3\"\nexport EMBEDDING_API_KEY=\"your_glm_api_key\"\nexport EMBEDDING_ENDPOINT=\"https://open.bigmodel.cn/api/paas/v4/\"\n```\n\n### 画像認識設定\n\n`SupportsVision` の設定により画像処理方法が変わります:\n\n| `SupportsVision` | Vision設定 | 画像処理 | `describe_image` tool |\n|:----------------:|:----------:|:--------:|:---------------------:|\n| `true` | 不要 | 画像を直接認識 | ❌ 無効 |\n| `false` | あり | URLを渡す、LLM判断でtool使用 | ✅ 有効 |\n| `false` | なし | 完全に無視 | ❌ 無効 |\n\n**パターン1: Vision対応モデル(GPT-4o等)**\n```json\n{\n \"OpenAI\": { \"ModelId\": \"gpt-4o\" },\n \"Vision\": { \"SupportsVision\": true }\n}\n```\n\n**パターン2: Vision非対応 + 別途Vision API**\n```json\n{\n \"OpenAI\": { \"ModelId\": \"glm-4-flash\" },\n \"Vision\": {\n \"SupportsVision\": false,\n \"ModelId\": \"glm-4v\",\n \"ApiKey\": \"your_vision_api_key\",\n \"Endpoint\": \"https://open.bigmodel.cn/api/paas/v4/\"\n }\n}\n```\n\n**パターン3: 画像機能なし**\n```json\n{\n \"OpenAI\": { \"ModelId\": \"gpt-4\" },\n \"Vision\": { \"SupportsVision\": false }\n}\n```\n\n---\n\n## 🛠️ 機能一覧\n\nBotが使用できる機能(Semantic Kernel Function Calling):\n\n### 📝 返信制御\n\n| 関数 | 説明 |\n|------|------|\n| `reply(content)` | 返信する |\n| `do_not_reply()` | 返信しない(見てるだけ) |\n\n### 🔍 履歴検索\n\n| 関数 | 説明 |\n|------|------|\n| `search_history(query)` | 過去の会話を検索 |\n\n### 📅 日付・時刻\n\n| 関数 | 説明 | 使用例 |\n|------|------|--------|\n| `get_time()` | 現在時刻 | `14:30` |\n| `get_date()` | 今日の日付 | `2024-01-15, Monday` |\n| `get_current_time()` | 日時すべて | |\n| `days_until(target)` | 指定日までの日数 | `christmas`, `newyear`, `tomorrow` |\n| `add_days(days)` | N日後の日付 | |\n| `days_between(start, end)` | 日付間の日数 | |\n| `day_of_week(date)` | 曜日を取得 | |\n\n### 🔢 計算\n\n| 関数 | 説明 |\n|------|------|\n| `add(a, b)` | 足し算 |\n| `subtract(a, b)` | 引き算 |\n| `multiply(a, b)` | 掛け算 |\n| `divide(a, b)` | 割り算 |\n| `sqrt(x)` | 平方根 |\n| `pow(x, y)` | 累乗 |\n| `abs(x)` | 絶対値 |\n| `round(x)`, `floor(x)`, `ceil(x)` | 丸め |\n| `compare(a, b)` | 大小比較 |\n\n### 📐 三角関数\n\n| 関数 | 説明 |\n|------|------|\n| `sin`, `cos`, `tan` | 三角関数 |\n| `asin`, `acos`, `atan` | 逆三角関数 |\n| `pi()`, `e()` | 定数 |\n\n### 🎲 ランダム\n\n| 関数 | 説明 | 使用例 |\n|------|------|--------|\n| `roll_dice(notation)` | サイコロ | `1d6`, `2d10`, `3d6+2` |\n| `coin_flip()` | コイントス | `表` / `裏` |\n| `pick_one(items)` | リストから選ぶ | `アイス,ケーキ,チョコ` |\n| `shuffle(items)` | シャッフル | |\n| `random_number(min, max)` | ランダム数値 | |\n\n### 🌐 外部データ\n\n| 関数 | 説明 |\n|------|------|\n| `read_url(url)` | URLの内容を読み込む |\n| `describe_image(url)` | 画像の内容を説明(LLM判断で呼び出し) |\n\n---\n\n## 🏗️ アーキテクチャ\n\n```\n┌─────────────────────────────────────────────────────────────────┐\n│ Discord Gateway │\n└─────────────────────────────┬───────────────────────────────────┘\n │\n ▼\n┌─────────────────────────────────────────────────────────────────┐\n│ DiscordBotService │\n│ • メッセージ受信 │\n│ • ユーザー名キャッシュ(メンション変換用) │\n│ • @username / xxxさん → Discordメンション変換 │\n└─────────────────────────────┬───────────────────────────────────┘\n │\n ▼\n┌─────────────────────────────────────────────────────────────────┐\n│ SemanticKernelMessageProcessor │\n│ (IMessageProcessor) │\n└─────────────────────────────┬───────────────────────────────────┘\n │\n ┌───────────────┼───────────────┐\n ▼ ▼ ▼\n┌──────────────────┐ ┌────────────────┐ ┌────────────────────┐\n│ ChatHistoryManager│ │RagHistoryStore │ │ Plugins │\n│ (直近N日分) │ │ (全期間+埋込) │ │ (Function Calling) │\n│ │ │ │ │ │\n│ • メモリ上の履歴 │ │ • SQLite │ │ • ReplyPlugin │\n│ • 誰が発言したか │ │ • Embedding │ │ • TimePlugin │\n│ を保持 │ │ • ベクトル検索 │ │ • MathPlugin │\n└──────────────────┘ └────────────────┘ │ • RandomPlugin │\n │ • UrlReaderPlugin │\n │ • ImageReader │\n └────────────────────┘\n │\n ▼\n┌─────────────────────────────────────────────────────────────────┐\n│ Semantic Kernel + AI Model │\n│ (OpenAI / GLM / Azure OpenAI / etc.) │\n└─────────────────────────────────────────────────────────────────┘\n```\n\n### データベース構成\n\n```sql\nCREATE TABLE chat_messages (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n guild_id INTEGER, -- サーバーID (DM の場合は NULL)\n channel_id INTEGER NOT NULL,\n user_id INTEGER NOT NULL,\n user_name TEXT NOT NULL, -- 発言者名\n role TEXT NOT NULL, -- 'user' or 'assistant'\n content TEXT NOT NULL,\n embedding BLOB, -- RAG用ベクトル (NULL可能)\n created_at TEXT NOT NULL\n);\n```\n\n---\n\n## 🎨 カスタマイズ\n\n### システムプロンプトの変更\n\n`appsettings.json` の `SystemPrompt` を編集:\n\n```json\n{\n \"SystemPrompt\": \"ChatterBotだよ。Discordでみんなと喋ってるだけの普通の人間...\"\n}\n```\n\n### 履歴設定\n\n```json\n{\n \"History\": {\n \"ChatHistoryMaxMessages\": 30, // 直近何メッセージを保持\n \"RagSearchLimit\": 5, // RAG検索の最大件数\n \"DefaultLoadDays\": 7, // 起動時に何日分読み込むか\n \"InactiveDaysThreshold\": 30 // 非アクティブチャンネル判定\n }\n}\n```\n\n### プラグインの追加\n\n#### 方法1: DLLで外部プラグインを作成\n\n1. 新しいクラスライブラリプロジェクトを作成\n2. `Microsoft.SemanticKernel` を参照に追加\n3. `[KernelFunction]` 属性で関数を定義\n\n```csharp\n// プラグイン例 (WeatherPlugin.cs)\nusing System.ComponentModel;\nusing Microsoft.SemanticKernel;\n\nnamespace MyPlugins;\n\npublic class WeatherPlugin\n{\n [KernelFunction(\"get_weather\")]\n [Description(\"指定した都市の天気を取得します\")]\n public async Task<string> GetWeather(\n [Description(\"都市名\")] string city)\n {\n // 実装\n return $\"{city}の天気: 晴れ\";\n }\n}\n```\n\n4. ビルドしてDLLを `plugins/` ディレクトリに配置\n5. Bot起動時に自動で読み込まれます\n\n**検出ルール**: `[KernelFunction]` 属性を持つメソッドが1つ以上ある public クラスが自動検出されます。\n\n```\nChatterBot/\n├── plugins/\n│ └── WeatherPlugin.dll # 自動読み込み\n├── ChatterBot.dll\n└── appsettings.json\n```\n\n#### 方法2: 内蔵プラグインを追加\n\n1. `ChatterBot.Plugins` 名前空間に新しいクラスを作成\n2. `[KernelFunction]` 属性で関数を定義\n3. `SemanticKernelMessageProcessor.cs` で登録\n\n### プラグインディレクトリ設定\n\n```json\n{\n \"Plugins\": {\n \"Directory\": \"plugins\" // DLLを配置するディレクトリ\n }\n}\n```\n\n---\n\n## 💻 開発\n\n### ビルド\n\n```bash\ndotnet build\n```\n\n### プロジェクト構成\n\n```\nChatterBot/\n├── Program.cs # エントリーポイント\n├── appsettings.json # 設定ファイル\n├── ChatterBot.csproj # プロジェクト定義\n│\n├── Abstractions/\n│ ├── IMessageProcessor.cs # メッセージ処理インターフェース\n│ ├── IChatHistoryManager.cs # チャット履歴管理\n│ ├── IRagHistoryStore.cs # RAGストア\n│ └── Models.cs # データモデル\n│\n├── Plugins/\n│ ├── ReplyPlugin.cs # 返信制御\n│ ├── HistorySearchPlugin.cs # 履歴検索\n│ ├── TimePlugin.cs # 日付・時刻\n│ ├── MathPlugin.cs # 計算・数学\n│ ├── RandomPlugin.cs # ランダム\n│ ├── UrlReaderPlugin.cs # URL読み込み\n│ └── ImageReaderPlugin.cs # 画像認識\n│\n└── Services/\n ├── DiscordBotService.cs # Discord連携\n ├── SemanticKernelMessageProcessor.cs # AI処理\n ├── ChatHistoryManager.cs # 履歴管理\n ├── SqliteRagHistoryStore.cs # RAG実装\n └── PluginLoader.cs # 外部プラグイン読み込み\n\nChatterBot.Tests.Console/ # テストプロジェクト\n├── Program.cs # コンテキスト認識テスト\n├── appsettings.json # テスト用設定\n└── SampleHistory.json # サンプル会話データ\n```\n\n### 使用パッケージ\n\n| パッケージ | バージョン | 用途 |\n|-----------|----------|------|\n| Discord.Net | 3.18.0 | Discord Bot |\n| Microsoft.SemanticKernel | 1.70.0 | AI統合・Function Calling |\n| Microsoft.Extensions.AI | 10.3.0 | Embedding生成 |\n| Microsoft.Data.Sqlite | 10.0.3 | データベース |\n\n---\n\n## 🧪 テスト\n\n### コンテキスト認識テスト\n\n会話履歴から直近のトピックを正しく認識できるかテストするコンソールアプリです。\n\n```bash\ncd ChatterBot.Tests.Console\n\n# 環境変数設定\nexport OPENAI_MODEL_ID=\"gpt-4o\"\nexport OPENAI_API_KEY=\"your_key\"\n# GLMの場合\n# export OPENAI_ENDPOINT=\"https://open.bigmodel.cn/api/paas/v4/\"\n\n# 実行\ndotnet run\n```\n\n#### テスト内容\n\n3つの異なるトピックの会話履歴を用意:\n- **トピックA**: ゲームの話(エルデンリング)\n- **トピックB**: 料理の話(カレー)\n- **トピックC**: 旅行の話(沖縄)\n\n曖昧な質問(「で、どう思う?」「続きは?」など)に対して、直近のトピック(旅行)に関連する応答が返ってくるかを確認できます。\n\n#### 使い方\n\n```\n=== 会話コンテキスト認識テスト ===\nモデル: gpt-4o\n最大履歴件数: 30\n\n--- メニュー ---\n1: トピックAのみ(ゲームの話)\n2: トピックA+B(ゲーム→料理)\n3: トピックA+B+C(ゲーム→料理→旅行)★推奨\n4: カスタム選択\nq: 終了\n\n選択: 3\n```\n\nこれにより、異なるLLM(4B/8B/GLM-4-Flash等)での会話コンテキスト認識精度を比較できます。\n\n---\n\n## 🤝 コントリビュート\n\n1. Fork する\n2. Feature ブランチを作成 (`git checkout -b feature/amazing`)\n3. コミット (`git commit -m 'Add amazing feature'`)\n4. Push (`git push origin feature/amazing`)\n5. Pull Request を作成\n\n---\n\n## 📄 ライセンス\n\nこのプロジェクトは [MIT License](LICENSE) のもとで公開されています。\n\n---\n\n<div align=\"center\">\n\n**Made with ❤️ by ChatterBot Team**\n\n[↑ トップに戻る](#-chatterbot)\n\n</div>\n\n---\n\n<a name=\"english\"></a>\n## 🇺🇸 English\n\nA Discord chatbot that naturally joins conversations. Uses Semantic Kernel + Function Calling where the AI decides whether to reply.\n\n### Quick Start\n\n```bash\n# Set environment variables\nexport DISCORD_BOT_TOKEN=\"your_token\"\nexport OPENAI_API_KEY=\"your_key\"\nexport OPENAI_MODEL_ID=\"gpt-4o\"\n\n# Run\ndotnet run\n```\n\n### Features\n\n- 🎭 Natural conversation participation\n- 🧠 Hybrid history management (ChatHistory + RAG)\n- 🌐 OpenAI-compatible API support\n- 🖼️ Flexible image handling (direct vision or tool-based)\n- 🛠️ Rich functions: calculation, time, random, URL reading, image recognition\n\n### Image Handling\n\n| `SupportsVision` | Vision Config | Image Processing | `describe_image` tool |\n|:----------------:|:-------------:|:----------------:|:---------------------:|\n| `true` | N/A | Direct image recognition | Disabled |\n| `false` | Set | URL passed, LLM decides to use tool | Enabled |\n| `false` | Not set | Completely ignored | Disabled |\n\nSee Japanese section above for detailed documentation.\n"}}}} |