ドキュメント

インストールから日常利用まで。本番導入で情シスが必要になる情報も含みます。

インストール

インストール方法は 3 つあります。どれか 1 つを選んでください。

デスクトップ版(推奨)

インストーラーをダウンロードして進めるだけです。デスクトップとスタートメニューにショートカットが作られます。初回起動はデータベースの初期化とモデル設定の読み込みで 20〜40 秒かかります。

Windows 10 以降に対応。macOS と Linux は現状ソースからのインストールになります。

Docker

社内サーバーに置いてチーム全員で使う場合はこちらです。

docker run -d --name yuan \
  -p 8080:8080 \
  -v $(pwd)/data:/app/data \
  -v $(pwd)/config:/app/config \
  --restart unless-stopped \
  yuan-assistant:latest

起動後 http://サーバーのアドレス:8080 を開きます。

data/ にデータベース、アップロードファイル、ログが入ります。config/ は設定ファイルです。この 2 つは必ずマウントしてください。しないとコンテナ再作成時に消えます。

ソースから

Python 3.10 以降が必要です。

git clone <取得元> yuan && cd yuan
pip install -r requirements.txt
python main.py web

フロントエンドを再ビルドする場合:

cd frontend && npm install && npm run build

動作要件

最小推奨
CPU2 コア4 コア以上
メモリ4 GB8 GB 以上
ディスク5 GB20 GB 以上
GPU不要VRAM 8 GB(ローカルモデル利用時)

クラウドモデル(OpenAI、Claude、Gemini)だけを使うなら GPU は不要です。完全オフラインでローカルモデルを動かす場合のみ必要になります。GPU なしでも動作しますが、かなり遅くなります。

初回起動

初回起動時に管理者アカウントが生成されます。パスワードは一度しか表示されません

デスクトップ版はウィンドウで表示します。サーバー版は起動ログに出力されます。

============================================
  管理者アカウントを作成しました
  ユーザー名:admin
  パスワード:xK9mP2vL8qR4nW7t
  ログイン後すぐに変更してください
============================================
このパスワードは二度と表示されず、ファイルにも書き出されません。控え忘れた場合、現実的な対処は data/ のデータベースを削除して初期化し直すことですが、全データが消えます。必ず控えてください。

ログインしたら最初に 設定 → アカウント でパスワードを変更してください。

次にモデルを設定する

モデルを設定しないと源は応答できません。方法は 2 つあります。

クラウドモデル設定 → モデル で API キーを貼り付けます。OpenAI、Anthropic、Google に対応。キーは暗号化してデータベースに保存され、設定ファイルには書かれません。

ローカルモデル設定 → 推論エンジン から Ollama をインストールします。詳しくはローカル推論を参照してください。

両方設定しておき、チャット欄の上で切り替えることもできます。

チャット

左が会話一覧、中央がスレッド、右がステータスパネルです。

モード

左上で 3 つのモードを切り替えられます。応答のスタイルと使えるツールが変わります。

モード用途
チャット質問、文章作成、翻訳
ワーク資料処理、データ分析、定期実行
コードコードの読み書き、Git、ターミナル

思考の深さ

チャット欄の横で調整できます。

  • ⚡ 高速 — すぐ答えます。単純な質問向け
  • ⚖️ バランス — 既定値
  • 🧐 深く — 考えてから答えます。難しい問題向けで、遅くコストも上がります
  • 🎨 創造的 — アイデア出し、ブレインストーミング

推論に対応したモデル(o シリーズ、Claude、Gemini など)でのみ有効です。他のモデルはこの設定を無視します。

ファイル添付

チャット欄にドラッグするか、クリップのアイコンから。PDF、Word、Excel、PowerPoint、テキスト、ソースコード、画像に対応します。

1 ファイル 25 MB まで。画像はビジョンモデルで解析し、文書はテキストを抽出してコンテキストに入れます。

画面コンテキスト

チャット欄の目のアイコンをオンにすると、送信時に「いまどのアプリを開いているか」「ウィンドウのタイトルは何か」も一緒に伝わります。

「このエラーはどういう意味」と聞くときに、状況を説明し直す必要がなくなります。オフにすれば何も収集しません。

音声

音声入力

Alt+V を押すか、チャット欄のマイクをクリックします。話し終えると文字起こしが入力欄に入るので、送信前に修正できます。

マイクの横で 2 つの認識エンジンを切り替えられます。

  • ローカル — ブラウザ内蔵の音声認識、またはローカルの faster-whisper。音声は端末から出ません。
  • クラウド — Whisper API に送信。精度が高くなります。

ローカル認識の初回利用時に音声モデル(約 150 MB)をダウンロードします。進捗が表示されます。

リアルタイム音声会話

Alt+V を 2 回押すとリアルタイムモードになります。双方向音声で、話し終えると同時に返答し、途中で遮ることもできます。

会議中、運転中、手が塞がっているときに便利です。このモードはクラウドのリアルタイム音声サービスを使うため、音声は端末外に出ます。完全にオフラインにしたい場合は上記のローカル認識を使ってください。

ツールと自動化

源は答えるだけでなく、ツールを使って作業を完了させます。「このフォルダの CSV をまとめてグラフにして Kevin に送って」と言えば、ファイル読み込み、計算、グラフ生成、メール送信に自分で分解して実行します。

実行中はスレッドにグレーの小さなラベルが表示され、何をしているかが分かります。

使えるツール

分類できること
ファイル読み取り、書き込み、検索、コピー、移動、削除
コードコード実行、シェルコマンド実行
Web検索、ページ取得、ブラウザ操作
ブラウザページ移動、クリック、フォーム入力、スクロール、抽出、スクリーンショット
バージョン管理status、diff、commit、log、branch
デスクトップスクリーンショット、画面の解析
記憶記憶、想起、過去の会話の検索
スケジュール定期タスクの作成
通知メール送信、各プラットフォームへの送信

全部で 43 個です。実際に使える数はライセンスによります。

権限と確認

破壊的な操作(ファイル削除、シェルコマンド実行、ファイル書き込み)は既定で確認を求めます。設定 → 権限 で自動承認に変更できますが、推奨しません。

ファイル操作はサンドボックスと明示的に許可したパスの中に限定されます。その外側には手が届きません。

ブラウザ自動化

実際のブラウザを操作できます。

あなた:example.com にアクセスして [email protected] でログイン、
        注文ページのデータを取得して

ページ移動、フォーム入力、クリック、抽出を順に実行します。同じ会話の中ではブラウザのログイン状態が保持されます。

ローカル推論

ローカル推論ならデータは自社のハードウェアから出ません。規制対象のデータを扱う場合の選択肢です。

セットアップ

設定 → 推論エンジン から Ollama をインストールします。VRAM を検出して適切なモデルサイズを提案します。

VRAM推奨モデル
なし(CPU のみ)qwen2.5:3bphi3:mini
4〜7 GBqwen2.5:3b
8〜15 GBqwen2.5:7bllama3.1:8b
16〜23 GBqwen2.5:14b
24 GB 以上qwen2.5:32b

ダウンロードの進捗はその場に表示されます。完了するとチャット欄の上のモデル選択に現れます。

Qwen、Llama、Gemma、DeepSeek、Mistral、Phi を含む 37 のモデルファミリーに対応しています。

プライバシーモード

設定 → プライバシー でプライバシーモードを有効にできます。有効にすると、誤ってクラウドモデルを選んでもローカル以外は使われません。

vLLM

GPU が複数枚ある場合、vLLM のほうがスループットが出ます。設定 → 推論エンジン で vLLM を選びモデルを指定してください。vLLM は GPU が必須で、CPU のみでは動きません。

正直に書いておくと、ローカルモデルの推論能力は最新のクラウドモデルには及びません。最高精度が必要な用途ではクラウド API を使うことになり、それは「データが外に出ない」という利点を手放すことを意味します。トレードオフです。

メッセージ連携

源をメッセージアプリに接続すると、顧客や同僚が直接やり取りできます。どのチャネルも同じ記憶とナレッジベースを共有します。

LINE 公式アカウント、Discord、Telegram、飛書に対応しています。

動かし方がそれぞれ違います。起動するプロセスの数と、公開 URL が要るかどうかに関わります。

プラットフォーム動作公開 URL
LINE独立プロセス、専用ポート必要
飛書web 本体と同じプロセス必要
Telegram独立プロセス、ポーリング不要
Discord独立プロセス、常時接続不要

LINE 公式アカウント

  1. LINE Developers で Messaging API チャネルを作成
  2. Channel Access Token と Channel Secret を取得
  3. config.yaml に記述:
line:
  channel_access_token: "取得したトークン"
  channel_secret: "取得したシークレット"
  webhook_port: 8443
  1. 別プロセスとして起動:
python main.py line
  1. Webhook URL を https://あなたのドメイン:8443/webhook に設定
LINE は専用ポート(既定 8443)で動く独立プロセスで、パスは /webhook です。web 本体の /api の下ではありません。リバースプロキシはこのポートに向けてください。

Discord

Discord Developer Portal でアプリと bot を作成し、Message Content Intent を有効にします。

discord:
  token: "bot のトークン"
python main.py discord

Discord は常時接続なので、公開 URL は不要です。

Telegram

BotFather でトークンを取得します。

telegram:
  token: "取得したトークン"
python main.py telegram

Telegram はポーリング方式なので公開 URL が不要で、社内ネットワークからでも動きます。

飛書

飛書オープンプラットフォームでカスタムアプリを作成します。

feishu:
  app_id: "cli_xxxx"
  app_secret: "取得したシークレット"
  verification_token: "イベント購読の検証トークン"

イベント購読 URL を https://あなたのドメイン/api/feishu/webhook に設定し、im.message.receive_v1 を購読します。web 本体が処理するのはこのチャネルだけで、別プロセスは不要です。


設定変更後は該当プロセスの再起動が必要です。複数のプラットフォームを同時に使う場合はそれぞれプロセスを起動してください。データベースは共有されます。

プロジェクトとファイル

プロジェクトは、関連する会話・ファイル・ルールをひとまとめにする仕組みです。

作成

サイドバーのプロジェクトアイコンから新規作成し、名前と説明を入力します。

フォルダの関連付け

プロジェクトにローカルフォルダを関連付けられます。関連付けると構造をスキャンし(.gitnode_modules__pycache__.gitignore の対象は自動で除外)、そのプロジェクト内での会話中はどんなファイルがあるかを把握した状態になります。

デスクトップ版では OS 標準のフォルダ選択ダイアログが開きます。

作業ルール

プロジェクトごとに固有のルールを持たせられます。

返答は必ず日本語の敬体で。
コードのコメントは英語。
金額を示すときは必ず通貨を明記。

このルールはそのプロジェクト内でのみ適用されます。

プロジェクト記憶

プロジェクトで蓄積した知識はそのプロジェクトに紐づきます。別のプロジェクトに切り替えても混ざりません。

設定

モデル

各社の API キーと既定モデルを管理します。キーは暗号化して保存され、画面上は末尾 4 文字のみ表示されます。必要なときは目のアイコンで確認できます。

メインモデルとフォールバックモデルを指定できます。メインが失敗すると自動的に切り替わります。

表示と言語

繁体字中国語、簡体字中国語、英語、日本語に対応。ダークとライトのテーマがあります。

ショートカット

デスクトップ版のグローバルショートカットです。どのアプリを使っていても効きます。

ショートカット動作
Alt+Mメインウィンドウの表示/非表示
Alt+V音声入力
Alt+Sスクリーンショットと解析
Alt+Dダッシュボードを開く
Alt+Pフローティングオーブを画面中央に呼び戻す

個人用 API トークン

自分のプログラムから源を呼び出す場合は、設定 → トークン でトークンを作成します。作成時に完全な値が一度だけ表示され、以降は接頭辞のみ確認できます。

バックアップ

設定 → バックアップ で手動バックアップ、または自動バックアップの設定ができます。データベースとアップロードファイルが対象です。全データを JSON でエクスポートすることもできます。

ライセンス

プランごとの内容

コミュニティProエンタープライズ
ユーザー数15無制限
1 日のメッセージ1001,000無制限
チャットと記憶
ローカル推論
音声アシスタント
業務自動化
メッセージ連携
プロジェクト管理
SSO
PostgreSQL / Redis / K8s
マルチ組織
監査とコンプライアンス出力

アクティベーション

設定 → ライセンス にこのマシンのデバイス ID(HWID)が表示されます。ご購入時にこの文字列をお知らせいただければ、ライセンスキーを発行します。

受け取ったキーを同じ画面に貼り付けて有効化してください。

1 つのキーは 1 台に紐づきます。マシンを移す場合はご連絡ください。

有効性の維持

ライセンスは定期的にライセンスサーバーへ確認を行います。オフラインの場合は 1 日間の猶予期間があり、それを超えると停止します。機能や有効期限を調整した場合、次回の確認時に自動で反映されます。再アクティベーションは不要です。

猶予は 1 日と短いため、長時間オフラインになる環境ではご注意ください。外部への通信が一切ない構成の場合は、オフラインライセンスについてご相談ください。

エンタープライズ導入

この章はインフラ担当者向けです。

PostgreSQL

既定は SQLite で、1 台構成なら十分です。複数台で状態を共有する場合は切り替えます。

database:
  url: "postgresql://user:password@db-host:5432/yuan"
  pool_size: 20

再起動するとスキーマが自動作成されます。

Redis

複数インスタンスでキャッシュとレート制限を共有する場合に必要です。

cache:
  backend: "redis"
  redis_url: "redis://redis-host:6379/0"

設定しない場合は各インスタンスがメモリ内キャッシュを持ちます。1 台なら問題ありませんが、複数台では整合が取れません。

バックグラウンドキュー

長時間ジョブを Celery ワーカーに逃がし、web プロセスを塞がないようにできます。

task_queue:
  backend: "celery"
  broker_url: "redis://redis-host:6379/1"

ワーカーの起動:

celery -A worker worker --loglevel=info

シングルサインオン

OIDC(Google、Microsoft Entra ID)と SAML 2.0(Okta、OneLogin など)に対応します。

sso:
  oidc:
    google:
      client_id: "..."
      client_secret: "..."
    azure:
      client_id: "..."
      client_secret: "..."
      tenant: "テナント ID"
  saml:
    idp_entity_id: "..."
    idp_sso_url: "..."
    idp_x509_cert: "..."

リダイレクト URI は https://あなたのドメイン/api/sso/{provider}/callback。SAML の SP メタデータは https://あなたのドメイン/api/sso/saml/metadata にあります。

アクセス制御

security:
  ip_whitelist: ["10.0.0.0/8", "192.168.1.0/24"]
  ip_blacklist: []
  max_sessions: 5
  login_lockout_attempts: 5
  login_lockout_minutes: 15

ip_whitelist が空なら制限なしです。CIDR 表記に対応します。

これらはエンタープライズ版が必要です。保護そのものはすべての版で有効です —— ログイン 5 回失敗で 15 分ロック、1 ユーザーあたり同時 5 セッションまで。エンタープライズ版で購入できるのはこの数値を変更する権利であって、保護の有無ではありません。session_limit / login_lockout を含まないライセンスでは、設定値は警告付きで無視され、既定の保護はそのまま働きます。

>

ip_whitelistip_blacklist は扱いが異なります。権限がない場合は無視するのではなく、サービスが起動を拒否します。IP 制限がかかっていると思い込んだまま無防備になるのを避けるためです。

権限は 4 段階(ゲスト、一般、上級、管理者)です。段階ごとに使えるツールが異なり、設定 → 権限 で調整できます。

監査とコンプライアンス

すべての操作が、実行者・操作内容・対象・IP・時刻とともに記録されます。管理者は管理画面から確認できます。

コンプライアンスレポートの出力:

GET /api/admin/compliance/report?start=<unix>&end=<unix>&format=csv

管理者権限が必要です。監査ログ、ログイン履歴、利用状況が含まれます。

データ削除:管理画面から特定ユーザーの全データ(会話、記憶、文書、アップロード)を一括削除できます。

Kubernetes

deploy/k8s/ にマニフェストがあります。Deployment(3 レプリカ)、Service、Ingress、HPA(CPU 70% で 2〜10 レプリカ)を含みます。

kubectl apply -f deploy/k8s/

データベースの接続情報と鍵は Secret に、設定は ConfigMap からマウントします。

暗号化

設定内の機密項目(API キー、トークン、パスワード)は保存時に暗号化され、ENC:: を接頭辞として保持されます。鍵はマシンに紐づくため、移設時は再入力が必要です。

データベースも暗号化できます。pysqlcipher3 を導入すると自動的に検出・有効化され、既存の平文データベースはその場で移行されます。

API リファレンス

源の API は自社のマシン上で動きます。当社のサーバーではありません。ベース URL はインストール先、たとえば http://localhost:8080https://yuan.yourcompany.com です。

既存システムへの組み込みに使えます。社内チケット、CRM、cron スクリプト、独自フロントエンドなど。

すべてのエンドポイントは /api/api/v1 の両方に同じ内容で載っています。以下は /api で統一します。

認証

設定 → トークン で個人用アクセストークンを作成します。完全な値は一度だけ返されます。

{ "token": "sk-asst-xxxxxxxxxxxxxxxxxxxx", "name": "自社連携" }

以降のリクエストにはこのヘッダーを付けます。

Authorization: Bearer sk-asst-xxxxxxxxxxxxxxxxxxxx
トークンは一度しか表示されず、保存されるのはハッシュのみです。紛失した場合は削除して作り直してください。

権限はトークンではなくアカウントに従います。アカウントの権限を下げれば、そのアカウントが持つすべてのトークンも同時に下がります。設定 → トークン で削除すれば即座に無効になります。

もう 1 つの経路があります。デスクトップ版では、ローカルマシン(127.0.0.1)からのリクエストはヘッダーなしでローカルユーザーとして認証されます。同じマシン上のスクリプトなら、トークンを作らずにそのまま呼び出せます。

源にはユーザー名とパスワードによるログインエンドポイントはありません。外部からの認証は上記の 2 つだけで、エンタープライズ版では別途 SSO が使えます。

まず 1 回叩いてみる

最短の完全な例です。1 文送って、1 文返ってきます。

curl -X POST http://localhost:8080/api/chat \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"message": "先週の売上をまとめて", "stream": false}'

戻り値:

{ "conversation_id": 42, "content": "先週の売上合計は ..." }

チャット

POST /api/chat が主要なエンドポイントです。

フィールド説明
messagestring必須。送信する内容
streambool既定は truefalse にすると 1 つの JSON で返るのでスクリプト向き
conversation_idint既存の会話に続ける。省略すると新規作成
model_namestringモデルを指定。省略時は既定値
modestringchatworkcode のいずれか
project_idstringプロジェクトに紐づけ、そのルールを適用

stream: true のときは text/event-stream で返り、各イベントは data: 行に JSON が 1 つ入ります。

イベント意味
{"content": "..."}応答の断片。連結して使う
{"done": true, "conversation_id": 42}完了
{"error": "..."}失敗

会話の管理

メソッドパス説明
GET/api/conversations一覧。searchlimit(上限 200、既定 50)、offset に対応
POST/api/conversations作成。titlemodel_nametemplate_id は任意
GET/api/conversations/{id}/messagesメッセージ取得(直近 100 件)
PUT/api/conversations/{id}/title名前変更
DELETE/api/conversations/{id}削除
GET/api/conversations/{id}/exportファイルとしてエクスポート
curl -H "Authorization: Bearer $TOKEN" \
  "http://localhost:8080/api/conversations?search=売上&limit=20"

ドキュメント

メソッドパス説明
POST/api/documents/upload単一アップロード(multipart、フィールド名 file
POST/api/documents/upload-batch一括アップロード
GET/api/documents一覧
GET/api/documents/search全文検索。キーワードは q
DELETE/api/documents/{id}削除
curl -H "Authorization: Bearer $TOKEN" \
  -F "[email protected]" \
  http://localhost:8080/api/documents/upload

アップロード後は自動的に分割・索引化され、会話中に参照できるようになります。

音声と画像

メソッドパス説明
POST/api/voice/stt音声認識。multipart、フィールド名 fileenginelocalcloud)と language は任意
POST/api/voice/tts音声合成。audio/mpeg を返す
GET/api/voice/statusエンジンの状態
POST/api/image/analyze内容の説明
POST/api/image/ocr文字認識
POST/api/image/describeアクセシビリティ用の説明
POST/api/image/compare複数画像の比較

システム

メソッドパス説明
GET/api/healthヘルスチェック。認証不要
GET/api/license/info現在のライセンス状態
GET/api/user現在のユーザー
GET/api/tokens自分のトークン一覧
POST/api/tokensトークン作成。body に name
DELETE/api/tokens/{id}トークン削除

/api/health は認証不要なので、ロードバランサーや監視の死活監視に使えます。

WebSocket

画面自体はツール実行状況をリアルタイムに受け取るため WebSocket を使っています。独自の対話型フロントエンドを作る場合にのみ必要で、通常の連携は上記の /api/chat で足ります。

ブラウザクライアントは、最初に個人トークンまたは JWT を有効期間が短い 1 回限りの WebSocket チケットと交換する必要があります。認証情報は HTTP の Authorization ヘッダーに入れ、URL には絶対に含めないでください。

POST http://localhost:8080/api/ws-ticket
Authorization: Bearer <トークン>

返された ticket は 1 回の接続試行にだけ使用できます。再接続するたびに新しいチケットを取得してください。

ws://localhost:8080/api/ws?ticket=<1 回限りのチケット>

WebSocket アップグレードに Authorization: Bearer ヘッダーを設定できるブラウザ以外のクライアントは、チケットの代わりにそのヘッダーを使用できます。

接続後は必ず最初に 1 通送ってください。サーバーは最初の 1 通を init フレームとして消費します。このフレームはセッションを設定するもので、接続を認証するものではありません。

{ "type": "init" }

その後に実際の内容を送ります。

{ "type": "chat", "message": "...", "conversation_id": 42, "mode": "work" }

サーバーから返る type には typingtool_calltool_resultchunkdoneerrorconversation_created があります。


エラー

エラーは常にこの形式で返ります。

{
  "error": "AUTH_1002",
  "message": "トークンの有効期限が切れています"
}

コードには接頭辞が付きます。

接頭辞範囲分類
AUTH_1xxx認証
RES_2xxxリソース
VAL_3xxx入力検証
RATE_4xxxレート制限
AI_5xxxAI サービス
CHAT_6xxxチャット
SRV_9xxxサーバー

分岐処理には error を使ってください。message の文言は表示言語によって変わります。

レート制限

上限を超えると 429 が返ります。1 日のメッセージ数はプランによります。ライセンスを参照してください。

トラブルシューティング

起動しない

まず data/logs/ のログを確認してください。デスクトップ版はトレイメニューからフォルダを開けます。

よくある原因:

ポートが使用中 — 既定は 8080 です。config.yamlweb.port を変更するか、占有しているプロセスを止めてください。

データベースがロックされている — 別のインスタンスが動いています。デスクトップ版は自動検出して既存ウィンドウをアクティブにします。サーバー版は旧プロセスの終了を確認してください。

モデル未設定 — 画面に表示されます。API キーを登録するか、ローカルモデルを導入してください。

応答が遅い

  • ローカルモデルの場合、設定 → 推論エンジン で VRAM の使用状況を確認してください。モデルが VRAM に収まらないと CPU にフォールバックし、大幅に遅くなります。小さいモデルに変更してください。
  • 「深く」は明らかに遅くなります。通常は「バランス」で十分です。
  • 会話が長くなるとコンテキストが膨らんで遅くなります。新しい会話を始めると改善します。

音声が反応しない

  • ブラウザまたは OS でマイクの許可が出ているか確認してください
  • ローカル認識は初回にモデルをダウンロードします。進捗が終わるまでお待ちください
  • デスクトップ版で Alt+V が効かない場合、他のアプリがそのショートカットを取得している可能性があります

メッセージ連携が届かない

  • Webhook URL は HTTPS で、外部から到達可能である必要があります
  • data/logs/ にリクエストが届いているか確認してください
  • Telegram は公開 URL 不要の polling モードで先にテストできます

ライセンスが無効になった

  • マシンからライセンスサーバーに到達できるか確認してください
  • ハードウェア(マザーボード、NIC、ディスク)を交換するとデバイス ID が変わり、再バインドが必要です
  • 1 日を超えてオフラインだと停止します。オンラインに戻れば自動的に回復します

それでも解決しない場合

data/logs/ の直近のログと、何をして、何を期待し、実際に何が起きたかを添えてご連絡ください。