Web Chat

Starnionのウェブ UIは、WebSocketをベースにしたリアルタイムチャットインターフェースを提供します。追加のアプリをインストールすることなくブラウザで直接AIエージェントと会話でき、画像、音声、ドキュメントファイルの転送やストリーミング応答をサポートしています。


概要

Webチャットチャンネルでは以下のことができます:

  • リアルタイムストリーミング:完全な回答を待つことなく、AIの応答が生成されるにつれてリアルタイムで表示されます
  • ファイル転送:チャットウィンドウで画像、音声ファイル、ドキュメントを添付して送信できます
  • ツール呼び出しの表示:AIが外部サービスにアクセスする際にどのツールを使用しているかをリアルタイムで確認できます
  • 会話管理:複数の会話(スレッド)を作成し、過去の会話履歴を表示できます
  • マルチチャンネル:Telegramと同じAIエージェントに接続され、会話履歴を共有します

主な機能

リアルタイムストリーミング応答

WebSocket接続を通じて、AIの応答がトークンごとにリアルタイムで送信されます。長い回答でも、生成プロセスを最初から見ることができるため、より速く感じられます。

ツール実行の表示

AIが天気検索、ウェブ検索、Googleカレンダーなどのツールを使用するとき、チャットウィンドウにどのツールが実行されたかが表示されます。

[ツール呼び出し: weather] 東京の現在の天気を検索中...
[ツール結果: weather] 東京:晴れ、22℃

ファイル添付と分析

チャットウィンドウで画像、音声、PDF、ドキュメントファイルを添付して送信できます。AIはファイルのコンテンツを分析して応答します。

ファイルタイプ 対応フォーマット 機能
画像 JPG、PNG、GIF、WebP 画像分析、説明、テキスト抽出
音声 MP3、WAV、OGG 音声テキスト変換、コンテンツ分析
ドキュメント PDF、DOCX、TXT コンテンツの要約、質問応答

生成ファイルギャラリー

AIが生成した画像や音声ファイルは自動的にギャラリーに保存されます。設定 → ギャラリーでいつでも確認できます。


セットアップ

Webチャットは追加の設定なしにStarnionをインストールした直後から利用できます。以下を確認するだけです。

サーバーへのアクセス

  1. ブラウザを開いてStarnionサーバーのアドレスにアクセスします。
    http://localhost:3893
    

    (本番環境では実際のドメインを使用してください。)

  2. アカウントを作成するかログインします。
  3. Web UIの左側のチャットエリアですぐにチャットを開始できます。

WebSocket接続の確認

Web UIはページが読み込まれるとWebSocketサーバーに自動的に接続します。ブラウザの開発者ツール(F12)→ ネットワークタブ → WSフィルターで接続状態を確認できます。

接続URL: ws://yourdomain.com/ws
認証: Bearerトークン(Authorizationヘッダーまたは?tokenクエリパラメータ)

リバースプロキシの設定(WebSocket)

NginxやCaddyなどのリバースプロキシを使用している場合、WebSocketアップグレードヘッダーを設定する必要があります。

Nginxの例:

location /ws {
    proxy_pass http://localhost:8080;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $host;
    proxy_read_timeout 180s;
}

Caddyの例:

reverse_proxy /ws localhost:8080 {
    transport http {
        versions 1.1
    }
}

使い方

新しい会話を開始する

  1. 左サイドバーの+ 新しい会話ボタンをクリックします。
  2. チャット入力ボックスにメッセージを入力してEnterキーを押すか、送信ボタンをクリックします。
  3. AIの応答がリアルタイムでストリーミングされます。

ファイルを送信する

  1. チャット入力ボックス横の添付アイコンをクリックするか、ファイルをチャットウィンドウにドラッグします。
  2. ファイルがアップロードされたら、メッセージと一緒に送信します。
  3. AIがファイルのコンテンツを分析して応答します。

AIモデルを選択する

チャットウィンドウの上部で会話に使用するAIモデルを選択できます。設定でAPIキーを登録したモデルのみが表示されます。

過去の会話を表示する

左サイドバーで過去の会話リストを確認し、任意のエントリをクリックするとその会話に移動します。


会話例

一般的な会話

私: Pythonでasync関数を作成するにはどうすればいいですか?
Bot: Pythonでは、async関数に `async def` キーワードを使用します。

    ```python
    import asyncio

    async def fetch_data(url: str) -> str:
        await asyncio.sleep(1)  # 非同期操作をシミュレート
        return f"Data from {url}"

    async def main():
        result = await fetch_data("https://example.com")
        print(result)

    asyncio.run(main())
    ```

    `await` はコルーチンの完了を待機し、その間イベントループは他のタスクを処理できます。

画像の送信と分析

(レシート画像を添付)
私: このレシートを整理してください

Bot: レシートの分析結果をお届けします。
    - 店舗:OOマート
    - 日付:2026-03-08
    - 合計:3,560円

    商品:
    - 牛乳(280円)
    - パン(420円)
    - 卵(600円)
    - 鶏胸肉(1,280円)
    - お菓子(980円)

    これを費用管理に記録しますか?

ツール呼び出しのある会話

私: 東京の現在の天気を教えてください

[ツール呼び出し: weather] 東京の天気を検索中...
[ツール結果: weather] 完了

Bot: 東京の現在の天気をお伝えします。
    - 状態:晴れ
    - 気温:18℃(体感温度16℃)
    - 湿度:45%
    - 午後は雲が増えますが、雨の予報はありません。

Web UIとTelegramの連携

[Web UIで]
私: 来週の読書目標:クリーンコードの第1〜5章を読む

[Telegramで後から]
私: 読書目標は何でしたっけ?
Bot: 来週の読書目標:クリーンコードの第1〜5章を読む。
    進捗を報告してください!

WebSocketプロトコル(開発者向けリファレンス)

Webチャットはゲートウェイのエンドポイント(GET /ws)を使用します。クライアントとサーバー間の通信フォーマットは以下の通りです。

接続

GET /ws
Authorization: Bearer <jwt-token>

またはクエリパラメータで認証:

GET /ws?token=<jwt-token>

クライアント → サーバー(InFrame)

{
  "id": "req-001",
  "method": "chat",
  "params": {
    "message": "こんにちは",
    "model": "gemini-2.0-flash",
    "thread_id": "uuid-of-conversation"
  }
}
フィールド 説明
id リクエスト識別子(応答にそのまま含まれます)
method 現在 chat のみサポートされています
params.message ユーザーメッセージ(必須)
params.model 使用するAIモデル(オプション)
params.thread_id 会話スレッドのUUID(オプション。省略すると新しい会話が開始されます)

サーバー → クライアント(OutFrame)

AIの応答は複数のイベントフレームとしてストリーミングされます。

テキストストリーミング:

{
  "type": "event",
  "id": "req-001",
  "event": "text",
  "payload": { "text": "こんにちは! " }
}

ツール実行:

{
  "type": "event",
  "id": "req-001",
  "event": "tool_call",
  "payload": { "tool": "weather", "text": "東京の天気を検索中..." }
}

ファイル応答(画像/音声):

{
  "type": "event",
  "id": "req-001",
  "event": "file",
  "payload": {
    "name": "generated_image.png",
    "mime": "image/png",
    "url": "https://storage.example.com/...",
    "size": 102400
  }
}

完了:

{
  "type": "event",
  "id": "req-001",
  "event": "done"
}

イベントタイプの概要:

イベント 説明
text AI応答テキストのチャンク
tool_call ツール呼び出しの開始
tool_result ツール実行結果
file 生成されたファイル(画像、音声など)
error エラーが発生しました
done 応答完了

重要な注意事項

同時接続

同じアカウントが複数のブラウザタブまたはデバイスから同時に接続されている場合、最新の接続がアクティブになります。以前の接続は自動的に閉じられます。

メッセージサイズの制限

WebSocketメッセージの最大サイズは64 KBです。ファイルのアップロードはREST API(/api/v1/upload)を通じて処理されるため、この制限は適用されません。

キープアライブ(Ping/Pong)

サーバーは50秒ごとにWebSocket Pingメッセージを送信します。60秒間応答がない場合、接続は終了します。ブラウザはPongに自動的に応答するため、追加の処理は不要です。

HTTPS/WSS の推奨

本番環境では、常にHTTPSとWSS(WebSocket Secure)を使用してください。HTTP/WSはネットワーク上でJWTトークンを公開する可能性があります。


トラブルシューティング

チャットで応答がない

  1. ブラウザコンソール(F12)でWebSocket接続エラーがないか確認します。
  2. サーバーのアドレスとポートが正しいことを確認します。
  3. リバースプロキシを使用している場合、WebSocketアップグレードヘッダーが設定されていることを確認します。

接続が頻繁に切断される

  • リバースプロキシの proxy_read_timeout またはタイムアウト設定を180秒以上に増やしてみてください。
  • ネットワークのファイアウォールがWebSocket接続をブロックしていないことを確認してください。

“agent service unavailable” エラー

エージェントサービス(Python)が実行されていないか、GatewayへのgRPC接続が失われているときに発生します。

# Docker Compose環境でサービスの状態を確認
docker compose ps

# エージェントサービスのログを確認
docker compose logs agent

アップロードしたファイルが画像を表示しない

MinIOオブジェクトストレージが設定されていない場合、ファイルストレージは無効になります。DockerComposeの設定でMinIOサービスが実行されていることを確認してください。


よくある質問

Q: Web UIからの会話をTelegramで確認できますか? A: はい、Web UIとTelegramは同じAIエージェントに接続されています。いずれかのチャンネルに記録されたものは他方から取得できます。

Q: 複数人が同じサーバーを使用できますか? A: はい、Starnionは複数ユーザーをサポートしています。各ユーザーはアカウントを作成し、独立した会話と設定を維持します。

Q: 会話履歴はサーバーにどのくらいの期間保存されますか? A: 会話履歴はPostgreSQLデータベースに保存されます。別途削除ポリシーがない限り、永続的に保存されます。設定で個別の会話を削除できます。

Q: インターネット接続なしで使用できますか? A: Starnionサーバーがローカルで実行されており、OllamaなどのローカルLLMを使用している場合、インターネット接続なしで使用できます。ただし、天気検索、ウェブ検索、Google連携などの外部APIを使用する機能はインターネットアクセスが必要です。

Q: モバイルブラウザで使用できますか? A: はい、Starnionのウェブ UIはレスポンシブに設計されており、モバイルブラウザで動作します。ただし、スマートフォンで便利に使用するには、Telegramチャンネルの使用をお勧めします。


Copyright © 2025 StarNion. All rights reserved.  |  v0.1.2