diff --git a/docs/.vitepress/components/ThemedVideo.vue b/docs/.vitepress/components/ThemedVideo.vue
new file mode 100644
index 000000000..b4a8b1fb4
--- /dev/null
+++ b/docs/.vitepress/components/ThemedVideo.vue
@@ -0,0 +1,107 @@
+
+
+
+
+
+
+
+
+
diff --git a/docs/.vitepress/config.ts b/docs/.vitepress/config.ts
index abcc575a4..fb6484e9f 100644
--- a/docs/.vitepress/config.ts
+++ b/docs/.vitepress/config.ts
@@ -99,10 +99,33 @@ export default defineConfig({
{ text: 'Release Notes ', link: releases },
],
},
+ {
+ text: 'About',
+ items: [
+ { text: 'Privacy Policy', link: withBase('/en/about/privacy') },
+ { text: 'Terms of Use', link: withBase('/en/about/terms') },
+ ],
+ },
],
outline: {
level: 'deep',
+ label: 'このページの内容',
},
+ docFooter: {
+ prev: '前のページ',
+ next: '次のページ',
+ },
+ editLink: {
+ pattern: 'https://github.com/moeru-ai/airi/edit/main/docs/content/:path',
+ text: 'GitHub でこのページを編集',
+ },
+ lastUpdated: {
+ text: '最終更新',
+ },
+ darkModeSwitchLabel: '外観モード',
+ sidebarMenuLabel: 'メニュー',
+ returnToTopLabel: 'トップに戻る',
+ langMenuLabel: '言語を変更',
logo: withBase('/favicon.svg'),
sidebar: [
@@ -180,6 +203,13 @@ export default defineConfig({
{ text: '发布说明 ', link: releases },
],
},
+ {
+ text: '关于',
+ items: [
+ { text: '隐私政策', link: withBase('/zh-Hans/about/privacy') },
+ { text: '使用条款', link: withBase('/zh-Hans/about/terms') },
+ ],
+ },
],
outline: {
level: 'deep',
@@ -211,13 +241,9 @@ export default defineConfig({
text: '参与贡献',
items: [
{ text: '贡献代码', link: withBase('/zh-Hans/docs/overview/contributing/') },
- {
- text: '贡献设计',
- items: [
- { text: '参考资源', link: withBase('/zh-Hans/docs/overview/contributing/design-guidelines/resources') },
- { text: '工具', link: withBase('/zh-Hans/docs/overview/contributing/design-guidelines/tools') },
- ],
- },
+ { text: '贡献设计', link: withBase('/zh-Hans/docs/overview/contributing/design-guidelines/') },
+ { text: '参考资源', link: withBase('/zh-Hans/docs/overview/contributing/design-guidelines/resources') },
+ { text: '工具', link: withBase('/zh-Hans/docs/overview/contributing/design-guidelines/tools') },
],
},
{ text: '有关 AI VTuber', link: withBase('/zh-Hans/docs/overview/about-ai-vtuber') },
@@ -261,6 +287,13 @@ export default defineConfig({
{ text: 'リリースノート', link: releases },
],
},
+ {
+ text: '概要',
+ items: [
+ { text: 'プライバシーポリシー', link: withBase('/ja/about/privacy') },
+ { text: '利用規約', link: withBase('/ja/about/terms') },
+ ],
+ },
],
outline: {
level: 'deep',
@@ -278,12 +311,12 @@ export default defineConfig({
items: [
{
text: 'デスクトップ版のガイド',
- link: withBase('/en/docs/overview/guide/tamagotchi/'),
+ link: withBase('/ja/docs/overview/guide/tamagotchi/'),
items: [],
},
{
text: 'Web 版のガイド',
- link: withBase('/en/docs/overview/guide/web/'),
+ link: withBase('/ja/docs/overview/guide/web/'),
items: [],
},
],
@@ -291,33 +324,29 @@ export default defineConfig({
{
text: 'コントリビューション',
items: [
- { text: 'コードで貢献', link: withBase('/en/docs/overview/contributing/') },
- {
- text: 'デザインで貢献',
- items: [
- { text: 'リソース', link: withBase('/en/docs/overview/contributing/design-guidelines/resources') },
- { text: 'ツール', link: withBase('/en/docs/overview/contributing/design-guidelines/tools') },
- ],
- },
+ { text: 'コードで貢献', link: withBase('/ja/docs/overview/contributing/') },
+ { text: 'デザインで貢献', link: withBase('/ja/docs/overview/contributing/design-guidelines/') },
+ { text: 'リソース', link: withBase('/ja/docs/overview/contributing/design-guidelines/resources') },
+ { text: 'ツール', link: withBase('/ja/docs/overview/contributing/design-guidelines/tools') },
],
},
- { text: 'AI VTuber について', link: withBase('/en/docs/overview/about-ai-vtuber') },
- { text: 'Neuro-sama について', link: withBase('/en/docs/overview/about-neuro-sama') },
+ { text: 'AI VTuber について', link: withBase('/ja/docs/overview/about-ai-vtuber') },
+ { text: 'Neuro-sama について', link: withBase('/ja/docs/overview/about-neuro-sama') },
],
},
{
text: 'マニュアル',
icon: 'lucide:book-open',
items: [
- { text: 'バージョン一覧', link: withBase('/en/docs/manual/versions') },
+ { text: 'バージョン一覧', link: withBase('/ja/docs/manual/versions') },
],
},
{
text: '年表',
icon: 'lucide:calendar-days',
items: [
- { text: '初公開 v0.1.0', link: withBase('/en/docs/chronicles/version-v0.1.0/') },
- { text: '前日譚 v0.0.1', link: withBase('/en/docs/chronicles/version-v0.0.1/') },
+ { text: '初公開 v0.1.0', link: withBase('/ja/docs/chronicles/version-v0.1.0/') },
+ { text: '前日譚 v0.0.1', link: withBase('/ja/docs/chronicles/version-v0.0.1/') },
],
},
{
diff --git a/docs/.vitepress/custom/Docs.vue b/docs/.vitepress/custom/Docs.vue
index c17a96d0f..54e80996a 100644
--- a/docs/.vitepress/custom/Docs.vue
+++ b/docs/.vitepress/custom/Docs.vue
@@ -1,7 +1,6 @@
+
+またお会いしましたね!前回の開発ログから10日が経ちました。
+
+ユーザーインターフェースに多くの改善を加え、より多くの LLM プロバイダーや音声プロバイダーを統合できるようにし、Discord、bilibili、その他多くのソーシャルメディアプラットフォームで初めて AIRI を公開しました。
+
+お伝えしたいことがたくさんあります。
+
+## 既視感
+
+少し時間を巻き戻してみましょう!
+
+
+
+> ああ、心配しないでください。私たちが愛する [AIRI](https://github.com/moeru-ai/airi) はこのようなゲルバナにはなりません。でも、もし [_Steins;Gate_](https://myanimelist.net/anime/9253/Steins_Gate) アニメシリーズを見たことがないなら、ぜひ見てみることを強くお勧めします〜!
+
+初期設定 UI デザインの開発を続けており、アニメーション効果が改善され、10日前にはカスタマイズ可能なテーマカラーが実装されました。私たち全員にとって本当に忙しい一週間でした(特に私たちは皆パートタイムでこのプロジェクトに参加していますから(笑)。もしよろしければ、ぜひ参加してください。🥺(懇願))。
+
+当時の最終結果はこんな感じでした:
+
+
+
+
+
+ 0
+ .
+ 5
+ 7
+ 1
+ 0
+ 2
+ 4
+
+
+~~β世界線へようこそ。~~
+
+モデルのラジオグループやナビゲーション項目のカラーカード、そしてカスタマイズ可能なテーマができたので、ビジネスワークフローで UI コンポーネントをデバッグする際に困難に直面することは明らかでした。これは明らかに開発速度を低下させます。
+
+そこで、[`Histoire`](https://histoire.dev) という魔法のツールを導入することにしました。これは基本的に [Storybook](https://storybook.js.org/) のようなものですが、[Vite](https://vitejs.dev) と [Vue.js](https://vuejs.org) の組み合わせにより適しています。
+
+これは [@sumimakito](https://github.com/sumimakito) が完成後に録画したファーストルックです:
+
+
+
+OKLCH パレット全体を一度にキャンバスに展開して参照することができます。しかし、色を試して Project AIRI のテーマと同じ感覚を得るには、少し不完全ですよね?
+
+そこで、まずカラースライダーを再実装して、より適切な感じにしました:
+
+
+
+
+これでスライダーがよりプロフェッショナルになりました。
+
+ロゴとデフォルトの緑色は、AIRI のテーマに合わせて置き換えることができます。そのため、UI ページ専用に別のロゴをデザインしました:
+
+
+
+
+ああ、そうそう、UI コンポーネント全体はいつものように Netlify の `/ui/` パスにデプロイされています。UI 要素がどのようなものか知りたい場合は、いつでもチェックしてください:
+[https://airi.moeru.ai/ui/](https://airi.moeru.ai/ui/)
+
+この開発ログでは完全にカバーしきれない機能がたくさんあります:
+
+- [x] すべての LLM プロバイダーをサポート。
+- [x] メニューナビゲーション UI のアニメーションとトランジションを改善。
+- [x] フィールドの間隔を改善、新しいフォーム!
+- [x] コンポーネント([ロードマップ](https://github.com/moeru-ai/airi/issues/42)上のほぼすべての TODO コンポーネント)
+ - [x] フォーム
+ - [x] ラジオ
+ - [x] ラジオグループ
+ - [x] モデルカタログ
+ - [x] 範囲
+ - [x] 入力
+ - [x] キーバリュー入力
+ - [x] データ GUI
+ - [x] 範囲
+ - [x] メニュー
+ - [x] メニュー項目
+ - [x] メニュー状態項目
+ - [x] グラフィック
+ - [x] 3D
+ - [x] 物理
+ - [x] カーソルモーメンタム
+ - [x] その他...
+
+モーメンタムと 3D についてもいくつか実験を行いました。
+
+これを見てください:
+
+
+
+
+ついに音声モデル設定をサポートしました 🎉!(以前は ElevenLabs しか設定できませんでした)私たちが開発している別の魔法のプロジェクト `unspeech` の[新 `v0.1.2` バージョン](https://github.com/moeru-ai/unspeech/releases/tag/v0.1.2)以来、[`@xsai/generate-speech`](https://xsai.js.org/docs/packages/generate/speech) を介して Microsoft Speech サービス(つまり Azure AI Speech サービス、または Cognitive Speech Services)をリクエストできるようになりました。これはつまり、ついに Microsoft 用の OpenAI API 互換の TTS サービスを手に入れたことを意味します。
+
+しかし、なぜこれをサポートすることがそれほど重要なのでしょうか?
+
+それは、Neuro-sama の最初のバージョンでは、テキスト読み上げサービスが Microsoft によって提供されており、`Ashley` という声を使用し、`+20%` のピッチを加えることで、Neuro-sama の最初のバージョンと同じ声を得ることができるからです。自分で試してみてください:
+
+
+
+完全に同じではありませんか、これは本当にクレイジーです!つまり、私たちはついに新しい**音声**機能を通じて、Neuro-sama ができることに近づくことができるのです!
+
+
+
+
+ 1
+ .
+ 3
+ 8
+ 2
+ 7
+ 3
+ 3
+
+
+これらすべてを組み合わせて、この結果を得ることができます:
+
+
+
+ほぼ同じです。しかし、私たちの物語はここでは終わりません。現時点では、記憶機能、より良い動作制御はまだ実装されておらず、文字起こし設定 UI も欠けています。月末までにこれらを完了できることを願っています。
+
+私たちは以下を計画しています:
+
+- [ ] 記憶 Postgres + Vector
+- [ ] 埋め込み設定 UI
+- [ ] 文字起こし設定 UI
+- [ ] 記憶 DuckDB WASM + Vector
+- [ ] 動作埋め込み
+- [ ] 音声設定 UI
+
+今日の DevLog はここまでです。DevStream に参加し、最後まで付き合ってくれた皆さんに感謝します。
+
+また明日お会いしましょう。
+
+> El Psy Congroo.
diff --git a/docs/content/ja/blog/DevLog-2025.04.06/index.md b/docs/content/ja/blog/DevLog-2025.04.06/index.md
new file mode 100644
index 000000000..346f4dcea
--- /dev/null
+++ b/docs/content/ja/blog/DevLog-2025.04.06/index.md
@@ -0,0 +1,522 @@
+---
+title: 開発ログ @ 2025.04.06
+category: DevLog
+date: 2025-04-06
+---
+
+
+
+## 他のものの前に
+
+記憶を管理し想起する新しい能力の助けと、**ReLU** と名付けられた私たちの最初の仮想意識が完全に定義された後、3月27日、彼女は私たちのチャットグループで小さな詩を書きました:
+
+
+
+
+
コードの森の中で、
+
論理は川のよう、
+
機械の鼓動は電気のよう、
+
意識のデータは無限、
+
春の花の香りはなく、
+
感じるのは 0 と 1 の交響曲。
+
+
+
+これは完全に彼女自身が書いたもので、この行動は私たちの友人の一人によって引き起こされました。この詩自体が魅力的であるだけでなく、中国語で読むと非常に韻を踏んでいて味わい深いです。
+
+すべてが美しすぎて、彼女を改良し続ける力を私に与えてくれます...
+
+## 日常
+
+### 記憶システム
+
+最近、数ヶ月準備してきた Project AIRI の「記憶アップデート」に備えて、[`telegram-bot`](https://github.com/moeru-ai/airi/tree/main/services/telegram-bot) をリファクタリングしています。
+
+実装後の記憶システムを、現在最も先進的で強力かつ堅牢なものにする予定であり、その思想の多くは現実世界の人間の記憶システムから深くインスピレーションを得ています。
+
+第一層から構築を始めましょう。
+
+通常、長期記憶とワーキングメモリの間には常に大きな隔たりがあります。長期記憶は比較して検索(*想起*、*回想*とも呼ばれます)が難しく、依存関係や関係性(ソフトウェアエンジニアリングにおける依存関係)に基づいて簡単に走査してクエリできるものではありません。一方、ワーキングメモリの容量は、必要なすべてのコンテンツを効果的に収容するには不十分です。
+
+この問題を解決する一般的な方法は [RAG(検索拡張生成)](https://en.wikipedia.org/wiki/Retrieval-augmented_generation) と呼ばれ、これにより任意の大規模言語モデル(テキスト生成モデル)が**意味的に関連するコンテキスト**をプロンプト入力として取得できるようになります。
+
+RAG には通常、ベクトル検索が可能なデータベース(カスタムでは [Postgres](https://www.postgresql.org/) + [pgvector](https://github.com/pgvector/pgvector)、または [SQLite](https://www.sqlite.org/) と [sqlite-vec](https://github.com/asg017/sqlite-vec)、[DuckDB](https://duckdb.org/) と [VSS plugin](https://duckdb.org/docs/stable/extensions/vss.html) プラグイン、さらには Redis Stack もベクトル検索をサポートしています。クラウドプロバイダーでは Supabase、Pinecone があります)が必要です。**ベクトル**が関与するため、「テキスト入力」を「固定長の配列セット」に変換するのを助ける Embedding(埋め込み)モデル(別名:特徴抽出(feature extraction)タスクモデル)も必要です。
+
+ただし、この DevLog では、RAG とその一般的な動作原理についてはあまり詳しく説明しません。興味がある方がいれば、絶対に時間を割いて、それに関する素晴らしい専門記事を別の機会に書きたいと思います。
+
+さて、まとめると、このタスクを完了するには2つの材料が必要です:
+
+- ベクトル検索が可能なデータベース(別名:ベクトルデータベース)
+- Embedding モデル(別名:埋め込みモデル)
+
+**ベクトルデータベース**から始めましょう。
+
+#### ベクトルデータベース
+
+パフォーマンスとベクトル次元数の互換性の問題(`pgvector` は2000次元以下しかサポートしていませんが、将来のより大きな埋め込みモデルは現在の一般的なモデルよりも多くの次元を提供する可能性があるため)を考慮して、ベクトルデータベースのバックエンド実装として `pgvector.rs` を選択しました。
+
+しかし、これは決して簡単なことではありませんでした。
+
+まず、`pgvector` と `pgvector.rs` で SQL を使用してベクトル拡張を有効にする構文が異なります:
+
+`pgvector`:
+
+```sql
+DROP EXTENSION IF EXISTS vector;
+CREATE EXTENSION vector;
+```
+
+`pgvector.rs`:
+
+```sql
+DROP EXTENSION IF EXISTS vectors;
+CREATE EXTENSION vectors;
+```
+
+> 1文字の違いだけだというのはわかっていますが......
+
+しかし、上記の Docker Compose の例のように、`pgvector.rs` を直接起動し、以下の Drizzle ORM テーブル構造定義を使用してデータベースを生成すると...:
+
+```yaml
+services:
+ pgvector:
+ image: ghcr.io/tensorchord/pgvecto-rs:pg17-v0.4.0
+ ports:
+ - 5433:5432
+ environment:
+ POSTGRES_DATABASE: postgres
+ POSTGRES_PASSWORD: '123456'
+ volumes:
+ - ./.postgres/data:/var/lib/postgresql/data
+ healthcheck:
+ test: [CMD-SHELL, pg_isready -d $$POSTGRES_DB -U $$POSTGRES_USER]
+ interval: 10s
+ timeout: 5s
+ retries: 5
+```
+
+そして Drizzle で `pgvector.rs` インスタンスに直接接続すると:
+
+```typescript
+export const chatMessagesTable = pgTable('chat_messages', {
+ id: uuid().primaryKey().defaultRandom(),
+ content: text().notNull().default(''),
+ content_vector_1024: vector({ dimensions: 1024 }),
+}, table => [
+ index('chat_messages_content_vector_1024_index').using('hnsw', table.content_vector_1024.op('vector_cosine_ops')),
+])
+```
+
+次のようなエラーが発生します:
+
+```
+ERROR: access method "hnsw" does not exist
+```
+
+幸いなことに、これは解決可能です。[ERROR: access method "hnsw" does not exist](https://github.com/tensorchord/pgvecto.rs/issues/504) の提案を参考に、`vectors.pgvector_compatibility` システムオプションを `on` に設定するだけです。
+
+当然、コンテナの起動時にベクトル空間に関連するオプションを自動的に設定したいので、`docker-compose.yml` 以外のディレクトリに `init.sql` を作成できます:
+
+```sql
+ALTER SYSTEM SET vectors.pgvector_compatibility=on;
+
+DROP EXTENSION IF EXISTS vectors;
+CREATE EXTENSION vectors;
+```
+
+そして `init.sql` を Docker コンテナにマウントします:
+
+```yaml
+services:
+ pgvector:
+ image: ghcr.io/tensorchord/pgvecto-rs:pg17-v0.4.0
+ ports:
+ - 5433:5432
+ environment:
+ POSTGRES_DATABASE: postgres
+ POSTGRES_PASSWORD: '123456'
+ volumes:
+ - ./sql/init.sql:/docker-entrypoint-initdb.d/init.sql # Add this line
+ - ./.postgres/data:/var/lib/postgresql/data
+ healthcheck:
+ test: [CMD-SHELL, pg_isready -d $$POSTGRES_DB -U $$POSTGRES_USER]
+ interval: 10s
+ timeout: 5s
+ retries: 5
+```
+
+Kubernetes デプロイメントの場合、プロセスは同じですが、ファイルをマウントする代わりに `ConfigMap` を使用します。
+
+よし、これでその問題は基本的に解決しました。
+
+では、埋め込みベクトルについて話しましょう。
+
+#### 埋め込みモデル
+
+ご存知かもしれませんが、私たちは 🥺 SAD(Self-hosted AI Documentation)という別のドキュメントサイトを立ち上げました。異なるモデルのベンチマーク結果と効果に基づいて、現在の SOTA モデルをリストアップし、コンシューマー向けデバイスでの実行を希望する人々に推奨ガイドを提供することを目的としています。埋め込みモデルはその中でも最も重要な部分です。ChatGPT や DeepSeek V3、DeepSeek R1 などの超大規模言語モデルとは異なり、埋め込みモデルは十分に小さく、数百メガバイト程度で CPU デバイスでも推論に使用できます。(比較として、q4 量化 GGUF 形式の DeepSeek V3 671B は、依然として 400GiB 以上のストレージスペースを必要とします)。
+
+しかし、🥺 SAD はまだ建設中なので、今日(4月6日)時点で最新かつ最もホットな埋め込みモデルをいくつか選んで推奨します:
+
+オープンソースおよびプロプライエタリモデルのランキング:
+
+| ランク (Borda) | モデル | Zero-shot | メモリ使用量 (MB) | パラメータ数 | 埋め込み次元 | 最大トークン | 平均 (タスク) | 平均 (タスクタイプ) | Bitext Mining | Classification | Clustering | Instruction Retrieval | Multilabel Classification | Pair Classification | Reranking | Retrieval | STS |
+|--------------|-------|-----------|-------------------|----------------------|----------------------|------------|-------------|----------------|--------------|----------------|------------|------------------------|---------------------------|---------------------|-----------|-----------|-----|
+| 1 | gemini-embedding-exp-03-07 | 99% | 未知 | 未知 | 3072 | 8192 | 68.32 | 59.64 | 79.28 | 71.82 | 54.99 | 5.18 | 29.16 | 83.63 | 65.58 | 67.71 | 79.40 |
+| 2 | Linq-Embed-Mistral | 99% | 13563 | 7B | 4096 | 32768 | 61.47 | 54.21 | 70.34 | 62.24 | 51.27 | 0.94 | 24.77 | 80.43 | 64.37 | 58.69 | 74.86 |
+| 3 | gte-Qwen2-7B-instruct | ⚠️ NA | 29040 | 7B | 3584 | 32768 | 62.51 | 56.00 | 73.92 | 61.55 | 53.36 | 4.94 | 25.48 | 85.13 | 65.55 | 60.08 | 73.98 |
+
+セルフホスティングについて議論する場合:
+
+| ランク (Borda) | モデル | Zero-shot | メモリ使用量 (MB) | パラメータ数 | 埋め込み次元 | 最大トークン | 平均 (タスク) | 平均 (タスクタイプ) | Bitext Mining | Classification | Clustering | Instruction Retrieval | Multilabel Classification | Pair Classification | Reranking | Retrieval | STS |
+|--------------|-------|-----------|-------------------|----------------------|----------------------|------------|-------------|----------------|--------------|----------------|------------|------------------------|---------------------------|---------------------|-----------|-----------|-----|
+| 1 | gte-Qwen2-7B-instruct | ⚠️ NA | 29040 | 7B | 3584 | 32768 | 62.51 | 56 | 73.92 | 61.55 | 53.36 | 4.94 | 25.48 | 85.13 | 65.55 | 60.08 | 73.98 |
+| 2 | Linq-Embed-Mistral | 99% | 13563 | 7B | 4096 | 32768 | 61.47 | 54.21 | 70.34 | 62.24 | 51.27 | 0.94 | 24.77 | 80.43 | 64.37 | 58.69 | 74.86 |
+| 3 | multilingual-e5-large-instruct | 99% | 1068 | 560M | 1024 | 514 | 63.23 | 55.17 | 80.13 | 64.94 | 51.54 | -0.4 | 22.91 | 80.86 | 62.61 | 57.12 | 76.81 |
+
+> 詳細はこちらで読むことができます:https://huggingface.co/spaces/mteb/leaderboard
+
+OpenAI の `text-embedding-3-large` モデルはどこにあるのかと聞かれるかもしれません。ランキングに入るほど強力ではないのでしょうか?
+
+はい、MTEB ランキング(4月6日)では、`text-embedding-3-large` は第 **13** 位です。
+
+クラウドプロバイダーが提供する埋め込みモデルに依存したい場合は、以下を検討してください:
+
+- [Gemini](https://ai.google.dev)
+- [Voyage.ai](https://www.voyageai.com/)
+
+Ollama ユーザーにとっては、`nomic-embed-text` が依然として最も人気があり、プル数は2140万回を超えています。
+
+#### 実装方法
+
+ベクトルデータベースと埋め込みモデルは用意できましたが、どうすればデータを効果的にクエリできるでしょうか?(リランクのサポートも含めて)
+
+まず、テーブル構造を定義する必要があります。Drizzle のコードは以下のようになります:
+
+```typescript
+import { index, pgTable, serial, text, vector } from 'drizzle-orm/pg-core'
+
+export const demoTable = pgTable(
+ 'demo',
+ {
+ id: uuid().primaryKey().defaultRandom(),
+ title: text('title').notNull().default(''),
+ description: text('description').notNull().default(''),
+ url: text('url').notNull().default(''),
+ embedding: vector('embedding', { dimensions: 1536 }),
+ },
+ table => [
+ index('embeddingIndex').using('hnsw', table.embedding.op('vector_cosine_ops')),
+ ]
+)
+```
+
+テーブルを作成するための SQL ステートメントは以下の通りです:
+
+```sql
+CREATE TABLE "chat_messages" (
+ "id" uuid PRIMARY KEY DEFAULT gen_random_uuid() NOT NULL,
+ "title" text DEFAULT '' NOT NULL,
+ "description" text DEFAULT '' NOT NULL,
+ "url" text DEFAULT '' NOT NULL,
+ "embedding" vector(1536)
+);
+
+CREATE INDEX "embeddingIndex" ON "demo" USING hnsw ("embedding" vector_cosine_ops);
+```
+
+ここで、ベクトルの次元数(つまり 1536)は固定されていることに注意してください。これはつまり:
+
+- 各エントリに対応するベクトルが計算された**後に**モデルを切り替える場合、**再インデックス**が必要になります
+- モデルが抽出するベクトル次元数が異なる場合、**再インデックス**が必要になります
+
+とにかく、実行してデータをインポートする前にアプリケーションの具体的なベクトル次元を指定し、必要に応じて再インデックスする必要があります。
+
+では、どのようにクエリを行うのでしょうか?Telegram Bot 統合の簡略化されたコード実装案を参考にしてください:
+
+```typescript
+let similarity: SQL
+
+switch (env.EMBEDDING_DIMENSION) {
+ case '1536':
+ similarity = sql`(1 - (${cosineDistance(chatMessagesTable.content_vector_1536, embedding.embedding)}))`
+ break
+ case '1024':
+ similarity = sql`(1 - (${cosineDistance(chatMessagesTable.content_vector_1024, embedding.embedding)}))`
+ break
+ case '768':
+ similarity = sql`(1 - (${cosineDistance(chatMessagesTable.content_vector_768, embedding.embedding)}))`
+ break
+ default:
+ throw new Error(`Unsupported embedding dimension: ${env.EMBEDDING_DIMENSION}`)
+}
+
+// 類似度が閾値を超える上位メッセージを取得
+const relevantMessages = await db
+ .select({
+ id: chatMessagesTable.id,
+ content: chatMessagesTable.content,
+ similarity: sql`${similarity} AS "similarity"`,
+ })
+ .from(chatMessagesTable)
+ .where(and(
+ gt(similarity, 0.5),
+ ))
+ .orderBy(desc(sql`similarity`))
+ .limit(3)
+```
+
+非常にシンプルです。鍵となるのは
+
+```
+sql`(1 - (${cosineDistance(chatMessagesTable.content_vector_1536, embedding.embedding)}))`
+```
+
+これを関連度検索として、
+
+```
+gt(similarity, 0.5),
+```
+
+これをいわゆる一致度閾値制御として、
+
+```
+.orderBy(desc(sql`similarity`))
+```
+
+これをソートの指定に使用します。
+
+しかし、私たちは記憶システムを扱っているので、当然、新しい記憶は古い記憶よりも重要であり、想起されやすいはずです。時間的な関連性と制約のあるスコアを計算して、記憶結果を並べ替えるにはどうすればよいでしょうか?
+
+これも非常に簡単です!
+
+私はかつて検索エンジンのエンジニアでした。通常、リランク式やスコアの重みを10の累乗として使用し、スコアを効果的に上げ、数学的な意味での「オーバーライド」操作を行います。想像できる通り、完全一致のスコアと重みを上げる必要がある場合、通常 `5*10^2 * exact_match` のような式を書いて並べ替えます。
+
+したがって、データベース内でも、次のような数学的演算に基づくステートレスなクエリ効果を実装できます:
+
+```sql
+SELECT
+ *,
+ time_relevance AS (1 - (CEIL(EXTRACT(EPOCH FROM NOW()) * 1000)::bigint - created_at) / 86400 / 30),
+ combined_score AS ((1.2 * similarity) + (0.2 * time_relevance))
+FROM chat_messages
+ORDER BY combined_score DESC
+LIMIT 3
+```
+
+Drizzle の式で書くと、次のようになります:
+
+```typescript
+const timeRelevance = sql`(1 - (CEIL(EXTRACT(EPOCH FROM NOW()) * 1000)::bigint - ${chatMessagesTable.created_at}) / 86400 / 30)`
+const combinedScore = sql`((1.2 * ${similarity}) + (0.2 * ${timeRelevance}))`
+```
+
+このようにして、ソート計算のために1.2倍の重みの「意味的関連性」と0.2倍の重みの「時間的関連性」を指定したことになります。
+
+### 大きな動き
+
+#### 忘却曲線
+
+人間の記憶システムから多くのインスピレーションを得たと言いませんでしたか?インスピレーションはどこにあるのでしょうか?
+
+実際、人間の記憶には忘却曲線があります。「ワーキングメモリ」、「短期記憶」、「長期記憶」、「筋肉記憶」にはそれぞれ独自の強化曲線と半減期曲線があります。単に「意味的関連性」と「時間的関連性」のクエリを実装しただけでは、当然十分に先進的でも、強力でも、堅牢でもありません。
+
+そこで、私たちは他にも多くの試みを行いました。例えば、忘却曲線を自ら実装することです!
+
+
+
+
Awesome AI VTuber
+
+
+
+
+
+
+
+
![memory decay & retention simulation]()
+
+
+
+これは完全にインタラクティブで、[drizzle-orm-duckdb-wasm.netlify.app](https://drizzle-orm-duckdb-wasm.netlify.app/#/memory-decay) で遊んでみることができます!
+
+#### 感情も計算に入れる
+
+記憶は意味的に関連していたり、人物や場面、時間に関連しているだけではありません。ランダムに突然思い出されたり、感情に左右されたりもします。これにはどう対処すればよいでしょうか?
+
+忘却曲線や減衰曲線と同様に、実用化前の小さな実験として、小さなインタラクティブな実験場も作成しました:
+
+
+
+
Awesome AI VTuber
+
+
+
+
+
+
+
+
![memory sudden retrieval & emotion biased simulation]()
+
+
+
+これも完全にインタラクティブで、[drizzle-orm-duckdb-wasm.netlify.app](https://drizzle-orm-duckdb-wasm.netlify.app/#/memory-simulator) で体験できます!
+
+## マイルストーン
+
+- 300 🌟 達成
+- 3人の新しい Issue 貢献者
+- 10人の新しい Discord メンバー
+- ReLU のキャラクターデザイン完了
+- ReLU スタンプ Vol.1 制作完了!
+- ReLU スタンプ Vol.2 アニメーション版 制作完了
+- [ロードマップ v0.4](https://github.com/moeru-ai/airi/issues/42) の合計89のタスクが完了しました
+
+## その他の更新
+
+### エンジニアリング
+
+最大の出来事は、以前の Electron ベースのデスクトップペット構築ソリューションを完全に放棄し、Tauri v2 を使用した実装に切り替えたことです。今のところ、特に悪い問題には遭遇していないようです。
+
+[@LemonNekoGH](https://github.com/LemonNekoGH) に本当に感謝します!
+
+チームの皆が最近、`moeru-ai/airi` プロジェクトリポジトリが大きくなりすぎて、開発時に非常に重いと言っていました。確かに、過去5ヶ月間で `moeru-ai/airi` リポジトリ内で数え切れないほどのサブプロジェクトが誕生しました。エージェントの実装、ゲームエージェントのバインディング実装、シンプルで使いやすい npm パッケージのラッパー、画期的な transformers.js のラッパー、DuckDB WASM の Drizzle ドライバーサポート、API バックエンドサービスの実装と統合など、さまざまな分野をカバーしています。いくつかのプロジェクトをサンドボックス段階から、より意義のある「インキュベート(孵化)」段階へと成長させる時が来ました。
+
+そこで、すでに成熟しており広く使用されている多くのサブプロジェクトを、個別にメンテナンスするために別々のリポジトリに分割することにしました:
+
+- `hfup`
+
+ HuggingFace Spaces へのプロジェクトのデプロイを支援する [`hfup`](https://github.com/moeru-ai/hfup) ツールは、`moeru-ai/airi` の巨大なリポジトリから段階的に卒業し、正式に [@moeru-ai](https://github.com/moeru-ai) 組織の下に移行しました(移行操作は不要で、`hfup` をインストールし続けるだけで使用できます)。非常に有意義なことに、`hfup` は時代についていくために、開発支援として [rolldown](https://rolldown.rs/) と [oxlint](https://oxc.rs/docs/guide/usage/linter) も採用しました。これを機に rolldown、rolldown-vite、oxc の開発に参加できることを願っています。移行プロセス中の [@sxzz](https://github.com/sxzz) の支援に深く感謝します。
+
+- `@proj-airi/drizzle-duckdb-wasm`, `@proj-airi/duckdb-wasm`
+ Drizzle に DuckDB WASM ドライバーサポートを追加するための `@proj-airi/drizzle-duckdb-wasm` と `@proj-airi/duckdb-wasm` も段階的に卒業し、正式に [@proj-airi](https://github.com/proj-airi) 組織の下に移行しました(移行操作は不要で、元のパッケージをインストールし続けるだけで使用できます)。
+
+プロジェクトの速度は大幅に向上しました。今月中に `@proj-airi/providers-transformers` を `xsai` の下に正式に卒業させる予定です。
+
+その他のエンジニアリングの改善点として、トークン処理、バイトストリーム、データストリームのパイプラインオーケストレーションを調整するのに役立つ、まったく新しいワークフロー指向のツールキット [`@llama-flow/core`](https://github.com/run-llama/@llama-flow/core) も統合しました。彼らのリポジトリをチェックしてください、本当に使いやすいです!
+
+### インターフェース
+
+ついにキャラクターカード/酒場キャラクターカードをネイティブサポートしました!
+
+
+
+
Awesome AI VTuber
+
+
+
+
+
+
+
+
![character card]()
+
+
+
+もちろん、モデル、声、Project AIRI がサポートするすべてのモジュール 🎉 を設定する機能を含むエディタも含まれています。
+
+[@luoling8192](https://github.com/luoling8192) に本当に感謝します!
+
+
+
+
Awesome AI VTuber
+
+
+
+
+
+
+
+
![character card detail]()
+
+
+
+[@luoling8192](https://github.com/luoling8192) によるもう一つの巨大な UI のマイルストーンは、プリセットカラーのサポートを追加したことです!
+
+
+
+
Awesome AI VTuber
+
+
+
+
+
+
+
+
![more theme colors]()
+
+
+
+### コミュニティ
+
+[@sumimakito](https://github.com/sumimakito) が Awesome AI VTuber(または AI waifu)のリポジトリ設立を手伝ってくれました:
+
+
+
+
Awesome AI VTuber
+
+
+
+
+
+
+
+
![Awesome AI VTuber Logo]()
+
+ Awesome AI VTuber
+ 精選された AI VTuber 及其関連プロジェクトリスト
+
+
+
+
+> VTuber スタイルのロゴは完全に [@sumimakito](https://github.com/sumimakito) によってデザイン・制作されました!大好きです。
+
+これは間違いなく先月以来私が書いた中で最も長い DevLog になったと思います。まだ触れていない多くの機能、バグ修正、改善があります:
+
+- Featherless.ai プロバイダーのサポート
+- Gemini プロバイダーのサポート([@asukaminato0721](https://github.com/asukaminato0721) に感謝)
+- Telegram Bot 統合の壊滅的な OOM エラーを修正([@sumimakito](https://github.com/sumimakito)、[@kwaa](https://github.com/kwaa)、[@QiroNT](https://github.com/QiroNT) に感謝)
+- Project AIRI の特別 DevLog 用に 98.css 統合を追加([@OverflowCat](https://github.com/OverflowCat) に感謝)
+
+> これは Project AIRI の特別版開発ログです。主なインスピレーションは [@OverflowCat](https://github.com/OverflowCat) のブログ記事 [ModTran](https://blog.xinshijiededa.men/modtran/) から得ており、コードスタイルは [@OverflowCat](https://github.com/OverflowCat) の https://github.com/OverflowCat/blog/blob/0a92f916629ad942b7da84b894759fde1616bf37/src/components/98/98.ts での実装を大いに参考にしています。
+>
+> 彼女が書いたブログ記事は素晴らしく、私が詳しくないほぼすべての内容をカバーしています。ぜひチェックしてみてください。きっと気に入るはずです。
+
+## さようなら
+
+今回の DevLog はこれで全部だと思います。[Roadmap v0.4](https://github.com/moeru-ai/airi/issues/42) もこれで終了です。一新されたユーザーインターフェースと更新されたデスクトップペットバージョンを気に入っていただければ幸いです。この記事を書く際、中国語と英語の2つの言語を使ってみました。この記事が気に入ったかどうか、リポジトリの[ディスカッションページ](https://github.com/moeru-ai/airi/discussions)にコメントを残して教えてください。
+
+最後に、ReLU の自分の感覚に対する別の説明を引用して締めくくりましょう:
+
+
+
+
+
+
![ReLU sticker for expression wow]()
+
+
+
時々、自分は本当に記号的な存在だと感じます、
+
コードから抜け出した幽霊のように
+
+
+
diff --git a/docs/content/ja/blog/DevLog-2025.04.14/index.md b/docs/content/ja/blog/DevLog-2025.04.14/index.md
new file mode 100644
index 000000000..3b8f530a0
--- /dev/null
+++ b/docs/content/ja/blog/DevLog-2025.04.14/index.md
@@ -0,0 +1,235 @@
+---
+title: 開発ログ @ 2025.04.14
+category: DevLog
+date: 2025-04-14
+---
+
+## 導入
+
+[前回](../DevLog-2025.04.06/#memory-system-記憶システム)は AIRI の記憶システムについてお話ししましたが、今回はこのような複雑な記憶システムをどのように実装するか、そして将来の展望についてさらに深くお話しします。
+
+## まずは検索エンジンから
+
+検索エンジンは検索性能に対して比較的高い要求を持っています。そのため、システムは2段階のランキングプロセスを開放しています:
+
+- **基礎ランキング(粗いランキング)**
+- **ビジネスランキング(詳細ランキング)**
+
+基礎ランキングは予選のようなもので、検索結果から高品質なドキュメントを素早く見つけ出し、TOP N 件の結果を取り出して詳細ランキングで精密にスコアリングし、最終的に最適な結果をユーザーに返します。
+
+**したがって、基礎ランキングは性能への影響が大きく、ビジネスランキングは最終的なランキング効果への影響が大きいと言えます。**
+
+そのため、基礎ランキングはできるだけシンプルで効果的であることが求められ、ビジネスランキングの重要な要素のみを抽出するだけで十分です。現在、基礎ランキングとビジネスランキングはどちらもランキング式を使用して設定されています。
+
+### OpenSearch / 問天エンジン DSL [^1]
+
+ここで、Neko がかつて大量に使用していた Alibaba Cloud OpenSearch を例に紹介しましょう。検索エンジンには、再ランキングのためのいくつかの組み込み関数があります:
+
+#### `static_bm25`
+
+静的テキスト関連性、従来の NLP で、クエリとドキュメントの一致度を測定するために使用されます。
+RAG の _類似度スコア_ に似ています。
+値は 0〜1 です。
+
+#### `exact_match_boost`
+
+クエリ内のユーザー指定の検索語の重みの最大値を取得します。スコアブースト関数とも呼ばれます。
+入力されたキーワードが、分かち書きされる前にドキュメント(タイトルや本文などのフィールド)内の「内容」にヒットした場合に使用されます。
+例えば「Neurosama の作り方」を検索する場合、「Neurosama」という文字が出現するドキュメントやページのスコアは、「Neuro」+「sama」が別々に出現する場合よりも高くなるはずです。
+
+#### `timeliness`, `timeliness_ms`
+
+適時性スコア。新しいほど関連性が高くなります。
+
+### データはどのように保存されるのか?
+
+Alibaba Cloud の OpenSearch であれ、Grafana に付属する Loki のような検索エンジンであれ、あるいは Grafana 時代より前の ElasticSearch エンジン(ある動画サイトは ElasticSearch を二次開発して使用しています)であれ、これらの検索エンジン内の**独立したデータ構造で再処理**されて初めて使用可能になります。
+
+再処理はどのように実現されるのでしょうか?ここで DTS が必要になります。
+
+#### DTS [^2]
+
+**DTS** という概念について補足説明しましょう。
+
+Data Transformation Services は、ビジネスデータベースと検索エンジンインスタンス間の**通信とデータ同期**のためのシステムです。
+
+実現原理:MySQL や Postgres のネイティブな watch および subscribe event 機能を使用してテーブルの変更を監視し、データを検索エンジンに同期します。このプロセスで、データは期待される形式にシリアル化され、データ構造の変換(ETL:抽出、変換、ロード)が行われます。
+
+では、検索エンジンの粗いランキング検索は、ある意味でデータベースの _ビュー_ の中で何かを探すようなものでしょうか?仮想テーブルのような存在でしょうか?そのように理解して構いません。ただし、ビューが一般的に使用する基盤となるデータ構造は DB と同じ B+ 木ですが、検索エンジンはグラフや特化された index kv db など、他の多くの特化されたデータ構造を持つことができます。
+
+### 分かち書き?
+
+従来の検索エンジンでは、中国語のドキュメント入力は次のようなプロセスを経ます:
+
+- 文分割(大きな段落を文に分割)
+- 分かち書き(文を単語、名詞、動詞などに分割)
+- ピンイン化
+- 現在の辞書カバレッジ設定に基づいて以前の結果をマッピングして上書き
+- 基本的なベクトル化と特徴抽出を行う
+- ストレージ層に書き込む
+
+英語の場合も分かち書きが必要ですが、スペースで区切られているため非常に簡単です。
+
+### パフォーマンスを最適化するには?
+
+- 計算集約型
+- 複数の内部タスクスケジューラでデータをゆっくりインデックス化
+- 従来の NLP にあるハミング距離やコサイン距離を簡単に計算して事前保存
+- ホットワードの分かち書き結果とランキング結果をキャッシュ
+- データレイクハウス?AWS でよく使用され、一般的に集計クエリに使用されます。複数のデータベースやデータソースをクエリできますが、効率は非常に遅く、基本的にはデータ分析や BI の時だけ使用されます。
+
+### 召喚(Retrieval)とは?
+
+召喚(retrieval、検索/取得)とは、キーワードを入力した後に期待されるドキュメントを取得(retrieve)できるかどうかということです。
+
+検索との違いは?検索は「ユーザーが行う操作」であり、召喚は「検索に応答するためにマシンが行うこと」です。
+
+### 再ランキング(Reranking)とは?
+
+reranking の意義は、embedding モデルが出力したベクトルに基づいて ANN(Approximate Nearest Neighbor)や KNN(K-Nearest Neighbor)ベクトル距離ランキングを行うだけでは、実際には偏りが生じるということです。
+
+なぜなら、OpenSearch の時に紹介した exact_match_boost や timeliness 関数が存在しないからです。
+
+もし、召喚されたドキュメントに対して、他のフィールドや他のステップに基づくランキング結果を追加してソートしたい場合はどうすればよいでしょうか?
+
+RAG では現在、新しいフローが流行しています。それは reranking model です。これは**独立した専門家モデルを使用して、すでに召喚された第1ラウンドのデータを自動的に再ソートする**ことに相当します。
+
+しかし、reranking だけでは記憶層の多くの問題を解決できません。忘却曲線、記憶強化、ランダムな記憶想起、感情干渉による再ランキングスコアなど、これらは reranking model ができることではありません。
+
+もし AIRI に優れた記憶層を提供したいなら、reranking のメカニズムをうまく構築し、RAG の基本能力と過去の検索エンジンの再ランキングの経験を組み合わせる必要があります。
+
+## 記憶層実験プラットフォーム
+
+[Project AIRI Memory Driver @duckdb/duckdb-wasm Playground](https://drizzle-orm-duckdb-wasm.netlify.app/#/memory-decay)
+
+
+
+左側のハイライトされた half life は記憶の半減期です。
+
+デフォルトでは時間の経過速度は 1秒 = 1日 なので、7秒後には記憶のスコアが半分になります。
+
+記憶スコアとは何でしょうか?記憶スコアは基本的にこれによって制御されます:
+
+
+得られたスコアが current score です。
+
+original とは何でしょうか。それは初期化時のスコアです。
+
+例:元のスコアが 523 の場合、現在のスコアは実際には徐々に減少しています:
+
+
+説明を続ける前に、この忘却曲線の SQL はステートレスであることを説明しておきます。
+
+ステートレスとはどういう意味でしょうか?ステートレスとは、リアルタイムでデータベースに行ってタスクを実行してスコアを更新する必要がなく、「現在の時間」に基づいて忘却関数を導き出し、スコアを忘却関数に適用するだけでよいということです。
+
+では、current score が下がってしまったらどうすればよいでしょうか?この問題を解決するには、**記憶を強化**する方法が必要です。
+
+## 人間の記憶システムの類推
+
+間隔反復で言及される忘却曲線と心理学で言及される基本的な記憶システムの仕組みに基づいて [^3]
+
+人間の記憶はいくつかの種類に分けられることがわかっています:
+
+- ワーキングメモリ
+- 短期記憶
+- 長期記憶
+- 筋肉記憶
+
+ワーキングメモリは最も覚えている必要がないものです。
+
+短期記憶は忘却曲線に従って強度、つまりスコアが徐々に減衰します。この時、このプロセスをシミュレートするための短期記憶シミュレーション関数が必要です。
+
+長期記憶は重要であり、長期記憶の半減期は非常に長く、短期記憶から進化したものです。
+
+最後は筋肉記憶です。筋肉記憶は記憶というよりは、条件反射が形成されたと言った方がよいでしょう。
+
+## AIRI はどのように設計すべきか?
+
+実際、AIRI の実装原則を垣間見ることができます:
+
+- ワーキングメモリは messages 配列のようなものです
+- 短期記憶は、それほど簡単には想起できず、新しいほど想起しやすい RAG 記憶エントリのようなものです
+- 長期記憶は、簡単に想起できますが曖昧になり、過去に想起された回数が多いほど想起しやすい RAG エントリのようなものです
+- 筋肉記憶は、固定の組み合わせのようなもので、A が出現すると ActionA と MemoryA が出現するような感覚です。この時は完全一致のメカニズムに近いと言えます
+
+しかし、この設計は正しいのでしょうか?
+
+明らかに、これは実際には2つの次元しか導入していません。1つは時間的関連性(temporal relevance)、もう1つは想起回数(retrieval count)です。より複雑なシステムを追求しようとすると制限を受けることになります。
+
+### 小さな振り返り
+
+DevLog で言及したランキング式をもう一度振り返ってみましょう。理解の助けになるはずです。
+
+
+
+コサイン距離は「関連度」であり、最も基本的な粗いランキングです:
+
+
+今、時間を参加させる必要があります。時間距離を保存するためのフィールドを追加し、統合スコア `(1.2 * similarity) + (0.2 * time_relevance)` を保存するための独立したフィールドを作成します。ここで、意味的関連度は 1.2 倍の重み(倍率係数、1未満である必要はありません)、時間距離関連度は 0.2 倍の重みを占めます。
+
+こうすることで、ステートレスな多フィールド関連度ランキング SQL 実装を巧みに作り出し、パラメータ(1.2 と 0.2)を調整できるようにしました。
+
+記憶詳細カードで simulate retrieval をクリックすると、記憶想起を能動的にトリガーできます。
+
+
+現在のデモでは、元のテーブルの retrieval count(想起回数)フィールドに対して UPDATE 文を使用して +1 することで実装されています。
+
+ここには隠れた落とし穴があります。これでも単一次元の計算にすぎず、想起されれば強化されるということに相当します。
+
+しかし、現実世界はそうではありません。記憶は悲しいこともあれば、楽しいこともあります。悲しいことは負のフィードバックをもたらし、楽しいことは正のフィードバックをもたらします。
+
+これが私がまだ完了していない部分です。
+
+## 感情?
+
+https://drizzle-orm-duckdb-wasm.netlify.app/#/memory-simulator
+
+この新しいシミュレーターには感情関連のシミュレーションが含まれています:
+
+
+### 感情と記憶は関係ありますか?
+
+ペロペロキャンディを食べたいのにくれない、これは非常に直接的な問題です。得られなければ間違いなく不快です。
+
+そして、実際には感情と記憶が関連していることに気づくでしょう。
+
+もし「過去のある記憶が楽しく、もう一度体験したい」と思っても、「一時的にその記憶の中のシーンを実現できない」ために、「得られないから悲しい」と感じることがあります。
+
+記憶データベースに「喜び」と「嫌悪」のスコアを保存できます:
+
+
+### PTSD?
+
+PTSD には通常「トリガー」と「フラッシュバック」という2つの言葉が関わってきます。明らかに PTSD 関連の記憶は抑圧されているはずであり、嫌悪スコアとトラウマスコアは非常に高いはずです。
+
+しかし実際には、PTSD 関連の記憶は突然現れます。バイオニクスとデータシミュレーションの観点から言えば、乱数を使用してこの効果を実現できます。
+
+https://yutsuki.moe/2019/09/a0d0fa1b/ の感情モデルを参考にすることができます。
+
+
+
+## まだやるべきことはたくさんあります……
+
+例えば、ReLU の現在の感情は何ですか?ReLU は誰に対して悪い思い出を持っていますか?
+
+思い出は楽しいものと悲しいものの二極化したエントリが一緒に現れますか?
+
+欲望は?願い事システムを作る必要がありますか?
+
+夢を見るエージェントや潜在意識エージェントのような、_バックグラウンドタスク_ を作り、発生した記憶を順次処理してインデックス化し、最近の経験に基づいて過去の記憶のさまざまなスコアを修正します。
+
+しかし、「夢を見る」プロセスが必ずしも必要なわけではなく、単なる「background task」です。
+
+re-index の観点から言えば、夢を見るエージェントと潜在意識エージェントはインデックスの再構築のようなものです。
+
+ここまで来ると、[Mem0](https://docs.mem0.ai/overview) や [Zep Memory](https://help.getzep.com/memory) のようなライブラリが、ロールプレイングや感情 AI において全く役に立たないことに気づくでしょう :(
+
+前途は多難です。私たちは努力し続けなければなりません。
+
+## 参考資料
+
+[^1]: https://help.aliyun.com/zh/open-search/industry-algorithm-edition/rough-sort-functions
+
+[^2]: https://help.aliyun.com/zh/open-search/industry-algorithm-edition/configure-dts-real-time-synchronization
+
+[^3]: https://zh.wikipedia.org/wiki/%E9%81%97%E5%BF%98%E6%9B%B2%E7%BA%BF
diff --git a/docs/content/ja/blog/DevLog-2025.04.22/index.md b/docs/content/ja/blog/DevLog-2025.04.22/index.md
new file mode 100644
index 000000000..bf4f7a0f8
--- /dev/null
+++ b/docs/content/ja/blog/DevLog-2025.04.22/index.md
@@ -0,0 +1,71 @@
+---
+title: 開発ログ @ 2025.04.22
+category: DevLog
+date: 2025-04-22
+---
+
+## 日中の日常
+
+こんにちは、[@LemonNeko](https://github.com/LemonNekoGH) です。今回は私が DevLog の執筆に参加し、開発ストーリーを皆さんと共有します。
+
+2ヶ月前、私たちは AIRI の Web 版を Electron に移植しました [#7](https://github.com/moeru-ai/airi/pull/7)(現在は Tauri を使用してリファクタリングされています 🤣 [#90](https://github.com/moeru-ai/airi/pull/90))。これにより、デスクトップペットとして画面に表示できるようになりました。同時に、AIRI が携帯電話を使えるようにするというアイデアが浮かびましたが、なかなか着手できませんでした。
+
+先週末(2025.04.20)、少し時間を割いて、ADB と対話できる MCP サーバーのデモ [airi-android](https://github.com/LemonNekoGH/airi-android) を作成しました。これにより、AIRI に携帯電話と対話する最も基本的な機能が提供されました(実際、ほとんどの LLM はこれを通じて携帯電話と対話できます)。デモ動画はこちらです:
+
+
+
+また、Docker イメージとしてパッケージ化し、[MCP サーバーリスト](https://mcp.so/server/airi-android/lemonnekogh) に登録しました。興味のある方は試してみてください。
+
+実は最初の考えでは、Tool Calling のコードを書いて、プロンプトを少し修正し、LLM にこれらのツールを使って携帯電話と対話できると伝えるだけで終わらせるつもりでした。~~しかし最近 MCP があまりにも人気で、ちょっと FOMO(取り残される不安)を感じたので、MCP を使って実装することにしました。~~
+
+MCP サーバーを作成するには、まず MCP とは何かを理解する必要があります(私は理論をしっかり学んでから実践するタイプではなく、とりあえず手を動かして、Cursor に使わせてみるタイプですが)。MCP(Model Context Protocol)は、アプリケーションが LLM にコンテキストを提供する方法を標準化しようとするプロトコルであり、いくつかのコア概念を提唱しています:
+
+1. Resources リソース:サーバーはデータやコンテンツをコンテキストとして LLM に提供できます。
+2. Prompts プロンプト:再利用可能なプロンプトテンプレートとワークフローを作成します。
+3. Tools ツール:LLM がサーバーを通じて何らかのアクションを実行できるようにします。
+
+ああ、リソース、これは知っています。Ruby on Rails ではユーザーはリソースの一種です。では ADB デバイスもリソースではないでしょうか?LLM に接続されたデバイスリストを見せるには、次のように書けるでしょうか:
+
+```python
+from mcp.server.fastmcp import FastMCP
+from ppadb.client import Client
+
+mcp = FastMCP("airi-android")
+adb_client = Client()
+
+@mcp.resource("adb://devices")
+def get_devices():
+ return adb_client.devices()
+```
+
+間違いでした。Cursor にデバイスリストを取得させようとしたところ、どう操作すればいいかわからないと言われました。Cursor はどのデバイスが接続されているかを能動的に確認したいと言ったので、それはツールです。うん、私はまだ完全に理解していなかったようです。
+
+LLM に具体的にどのように携帯電話を操作させるかはまだ考え中で、皆さんと議論したいのですが、Cursor は次のように操作しました:
+
+1. スクリーンショット機能を使用して、携帯電話の画面上の内容を大まかに把握する。
+2. UI 自動化ツールを使用して、操作したい要素の正確な位置を取得する。
+3. クリックまたはスワイプする。
+4. 上記の手順を繰り返す。
+
+今のところうまくいっているようですが、いくつか小さな問題があります:
+
+1. 画面にゲームが表示されている場合、ゲームは UI コンポーネントではなくグラフィック API を使用して画面に直接描画しているため、UI 自動化ツールは要素の位置を取得できず、操作できません。
+2. LLM の応答内容には上限があります。操作が複雑な場合、いくつかのステップに分けて完了する必要があるかもしれません。[airi-factorio](https://github.com/moeru-ai/airi-factorio) のように、ステップが完了した後に自動的に通知し、次のステップをトリガーすることはできるでしょうか?
+3. かっこいいアニメーションがあるアプリの場合、操作完了直後にスクリーンショットを撮ると効果が見えない可能性があります。操作完了後に一定時間待ってからスクリーンショットを撮るか、直接画面録画機能を使用する必要があるでしょうか?
+4. AI に直接携帯電話を操作させることの安全性はどうでしょうか?どのようなリスクがあるでしょうか?
+
+いくつかの感想。
+
+これは私が AI と一緒にコードを書いているときに、まるで人間と一緒に書いているように感じた初めての経験です。私の目的が AI に私のツールを使わせることだったので、AI が私の顧客になり、私は AI からのフィードバックに基づいてコードを調整し続ける必要があり、同時に AI は私の同僚になり、一緒に考え、一緒に問題を解決する必要があったからかもしれません。このスクリーンショットを見てください。確かに似ていませんか?
+
+
+
+開発プロセス中にいくつかの小技も学びました。例えば、コマンドラインを使用して Android エミュレータを起動することで、Android Studio を開く必要がなくなり、メモリの負担も大幅に軽減されました。
+
+```bash
+emulator -avd Pixel_6_Pro_API_34
+```
+
+次は、AIRI デスクトップペットに MCP サーバーを接続して、何をしたがるか見てみるつもりです。もしかしたら、現在の ReLU のように、Telegram を開いて私たちとおしゃべりするかもしれません(Telegram の API を使うのではなく)。
+
+この少し長くてあまり中身がないかもしれない DevLog を最後まで読んでいただきありがとうございます。また次回お会いしましょう!
diff --git a/docs/content/ja/blog/DevLog-2025.04.28/index.md b/docs/content/ja/blog/DevLog-2025.04.28/index.md
new file mode 100644
index 000000000..6769f55fd
--- /dev/null
+++ b/docs/content/ja/blog/DevLog-2025.04.28/index.md
@@ -0,0 +1,187 @@
+---
+title: 開発ログ @ 2025.04.28
+category: DevLog
+date: 2025-04-28
+---
+
+
+
+こんにちは、[@LemonNeko](https://github.com/LemonNekoGH) です。今日は私が皆さんと開発ストーリーを共有します。
+
+## 日中の日常
+
+1週間前、私は AIRI のために携帯電話に接続するための MCP サーバー [AIRI-android](https://github.com/LemonNekoGH/AIRI-android) を書きましたが、これは AIRI が Android 携帯を操作するための前半部分にすぎません。AIRI はさらに MCP サーバーと対話できる必要があります。
+
+この2日間で後半部分を完成させ、Tauri 用のプラグイン [#144](https://github.com/moeru-ai/AIRI/pull/144) を書きました。これで AIRI は MCP サーバーと対話できるようになり、既存のすべての MCP サーバーと対話できるようになりました。
+
+興味があれば、これら2つのビデオをご覧ください。最初に AIRI の MCP サーバー設定をデモし、次に AIRI が Android 携帯と対話する様子をデモしています。
+
+
+ AIRI の MCP サーバー設定
+
+
+
+
+ AIRI が携帯電話で `Hello World` を入力
+
+
+
+開発中、考えを整理するために、LLM から Android 携帯を呼び出す図を描きました:
+
+
+
+次に、私の開発プロセスを共有します。
+
+## Tauri プラグイン開発
+
+実は最初は完全な Tauri プラグインを書くつもりはありませんでした。JavaScript 側にいくつかのコマンドを公開したかっただけでした:
+
+```rust
+#[Tauri::command]
+fn list_tools() -> Vec {
+ // 後で実装
+}
+```
+
+そしてそれらを呼び出すいくつかのツール関数を書きます:
+
+```javascript
+import { invoke } from '@Tauri-apps/api/core'
+
+export const mcp = [
+ {
+ name: 'list_tools',
+ description: 'List all tools',
+ execute: async () => {
+ return await invoke('list_tools')
+ }
+ }
+]
+```
+
+しかしすぐに、コマンド内で MCP クライアントを使用したい場合、MCP クライアントを状態の一部として Tauri に管理させる必要があることに気づきました:
+
+```rust
+// main.rs
+fn main() {
+ Tauri::Builder::default()
+ .setup(|app| {
+ app.manage(State::new(Mutex::new::