「[[.NET 開発基盤部会 Wiki>http://dotnetdevelopmentinfrastructure.osscons.jp]]」は、「[[Open棟梁Project>https://github.com/OpenTouryoProject/]]」,「[[OSSコンソーシアム .NET開発基盤部会>https://www.osscons.jp/dotNetDevelopmentInfrastructure/]]」によって運営されています。

-[[戻る>LLM系ツール]]

*目次 [#gbdaba12]
#contents

*概要 [#lbd59853]
LLMチャット系ツール:ローカルまたはWeb上でLLM(大規模言語モデル)やAIアプリのインターフェースを作る用途に使われる。

*詳細 [#gab9a878]

**Gradio UI [#md161b4d]
-NoteBook の 1セルからUIを作成して起動できる(NoteBookではない通常のPythonでも良い)。
-DSが「モデルのデモを作る」「プロトタイプ・PoCを共有する」「内部レビューやユーザテストを行う」などの用途に最適

-アーキテクチャ
--Python関数を画面全体の再描画の無いSPA風UI化する。
--Pythonコードはクライアントではなくサーバーで動作する。
--...が、何れもローカルで動く(共有時はProxy経由になる)

-本番・商用環境では、~
以下のようなパッケージに置き換えられることが多い。
--SPA系UI(Next.js/React/Vue)+Python系WebAPIフレームワーク(FastAPI/Flask/Django)
--SPA系を使用しない場合、Streamlit(CLIでも実装可能なチャットUIをWeb化するなどの目的で使用)

-参考
--[[LLM Engineering:Master AI、Large Language Models&Agents]]
--[[The Complete Agentic AI Engineering Course (2025)]]

***インストール [#yc5069fa]
パッケージのインストール
 pip install gradio

***動作確認 [#he9d235e]

-Gradioによる画面定義
 import gradio as gr
 
 def greet(name):
     return "Hello " + name + "!"
 
 demo = gr.Interface(fn=greet, inputs="text", outputs="text")
 demo.launch(inbrowser=True)

-Session的な概念を加えたGradioによる画面定義
 import gradio as gr
 
 # greet関数に state を追加
 def greet(name, session_state):
     if session_state is None:
         session_state = []  # 初回は空リスト
     session_state.append(name)  # 入力された名前をセッションに追加
     greeting = "Hello " + name + "!"
     history = "Session History: " + ", ".join(session_state)
     return greeting, session_state, history
 
 with gr.Blocks() as demo:
     session_state = gr.State([])  # セッション状態の初期化
     name_input = gr.Textbox(label="Your Name")
     output_text = gr.Textbox(label="Greeting")
     history_text = gr.Textbox(label="Session History")
     
     greet_btn = gr.Button("Greet")
     greet_btn.click(
         greet, 
         inputs=[name_input, session_state], 
         outputs=[output_text, session_state, history_text]
     )
     
 demo.launch(inbrowser=True)

-更に、チャットUIを表示させてみる(履歴の考慮もアリ)。
 import os
 import gradio as gr
 from openai import OpenAI
 
 client = OpenAI()
 
 def chat_fn(message, history):
     # history は [{role: "...", content: "..."}, ...] の配列
     messages = history + [{"role": "user", "content": message}]
     print(messages)
     response = client.chat.completions.create(
         model="gpt-4o-mini",
         messages=messages,
     )
 
     # message は dict なので .content を使う
     reply = response.choices[0].message.content
 
     return reply
 
 demo = gr.ChatInterface(
     chat_fn,
     title="Gradio × OpenAI 2.8.1 Chat UI",
 )
 
 demo.launch(inbrowser=True)

-更に、チャットにRAGを追加してみる(LlamaIndexでindexを構築済みである前提)。
 import os
 import gradio as gr
 from openai import OpenAI
 
 client = OpenAI()
 
 def chat_fn(message, history, use_option):
 
     if use_option:
         print("RAG")
 
         retriever = index.as_retriever(similarity_top_k=2)
         nodes = retriever.retrieve(message)
 
         temp = ""
         for node in nodes:
             temp += node.text
             temp += f"\n--------------------------------------------------\n"
         
         message += f"\n検索で取得した参考情報:\n" + temp
 
     else:
         print("NORMAL")
 
     # history は [{role: "...", content: "..."}, ...] の配列
     messages = history + [{"role": "user", "content": message}]
     print(messages)
     response = client.chat.completions.create(
         model="gpt-4o-mini",
         messages=messages,
     )
 
     # message は dict なので .content を使う
     reply = response.choices[0].message.content
 
    return reply
 
 checkbox = gr.Checkbox(label="RAGモード", value=False)
 
 demo = gr.ChatInterface(
     chat_fn,
     additional_inputs=[checkbox],
     title="Gradio × OpenAI 2.8.1 Chat UI",
 )
 
 demo.launch(inbrowser=True)

**[[Streamlit>#g59f451b]] [#v83ca8fc]
[[Gradio UI>#md161b4d]]に次いでプロトタイプ向きだが、本番向きでもある(大規模な商用からは一段落ちる)。

-Pythonスクリプトを画面全体の再描画が無いSPA風UI化する。
-Pythonスクリプトに「画面全体の再描画が無いSPA風UI」を追加する。

-Pythonスクリプトにst.xxxレイヤを追加、
--スクリプト全体が再実行されるが、UIは(エンジンが実行結果を解釈し)部分更新。
--結果、JSP/ASPとは異なり、画面全体の再描画の無いSPA風UIが実現される。

-「Stream」litである理由はデータストリームとの親和性。
--アプリの状態をストリームとし、UIをリアクティブに再構築
--UIコンポーネントにはダッシュボードを構成するグラフ出力なども含む。

-LI互換性は派生的メリット
--標準出力をst.xxxに置き換えれば、CLIを迅速にWeb化できる。
--LLMに限定したものではないが、CLIのLLMとは相性が良い。

※ 参考:https://github.com/OpenTouryoProject/DxCommon/blob/master/Notebook/path/LLM_Streamlit.py

***インストール [#z7a3f1da]
パッケージのインストール
 pip install streamlit

***動作確認 [#a92078db]
-実行する。
 streamlit run LLM_Streamlit.py

-UIにアクセスする。
 http://localhost:8501/

**[[Open WebUI>#z2f80f6b]] [#y9e8d0ea]
OSSの代表格っぽい名称のChatUIプロダクト

-Pythonで実装されたChatGPT風のUIで、モデル設定のURLからサーバサイドで実行されている事が解る。
-LLMはサーバー・サイド、クライントはSPAっぽいので、サーバー + クライアント・サイド
-主に Ollama やローカル LLM をチャット形式で操作するために使われ、多くのモデル(LLaMA, Mistral, etc)と互換性あり。

***インストール [#d61ec687]
-WSL2からDockerを起動するには...
--The command 'docker' could not be found in this WSL 2 distro. #Docker - Qiita~
https://qiita.com/chovin/items/3057b35b776f70c3bcb5

-WSL2からDockerでOpen WebUIを起動して、
 docker run -d -p 5955:8080 --add-host=host.docker.internal:host-gateway -v open-webui:/app/backend/data --name open-webui --restart always ghcr.io/open-webui/open-webui:main

***動作確認 [#kdd835e0]
-以下のURLにアクセスすると(何故か)WLS2上のOllamaにアクセスできる。
 http://127.0.0.1:5955/

-設定を確認すると、モデルは以下のように設定されており、~
コンテナからホスト上のサービスにアクセスしているらしい。
 http://host.docker.internal:11434

**[[Chainlit>#mcd99ab0]] [#of654238]
LLMエージェントとの対話に特化したチャットアプリやツールを素早く構築するためのフレームワーク
-その名称から、LangChain、DataStream(≒[[Streamlit>#g59f451b]])と相性がいい。
-ただし、Pythonスクリプト全体ではなくイベント駆動で動作するとのこと。
-ただし、[[Streamlit>#g59f451b]]と異なり、Pythonスクリプト全体ではなくイベント駆動で動作するとのこと。

**[[Ollama-ui>#l8d7482d]] [#oe1a4d66]
「[[Ollama]]ならWebUI提供するよね」と言う感じ。

**[[ChatKit>#jd7ba186]] [#e890eebd]
-「[[OpenAI]]ならWebUI提供するよね」と思い探ってみたらあったものの、
-古くからあるツールと見せかけて、最新のツールでAgentKitの一部らしい。

*参考 [#e21fe112]

**Gradio UI [#td5f139c]
-機械学習向けWeb UIライブラリ Gradio #Python - Qiita~
https://qiita.com/kzkymn/items/901ba79052190e428697

-gradio 入門|npaka
--(1) - 事始め~
https://note.com/npaka/n/nb9d4902f8f4d
--(2) - Interface~
https://note.com/npaka/n/nb2e78a8a89f5

**Streamlit [#g59f451b]
-streamlitを使ったお手軽Webアプリ開発 #Python - Qiita~
https://qiita.com/sypn/items/80962d84126be4092d3c

-Streamlit入門+応用 ~ データ分析Webアプリを爆速で開発する #Python - Qiita~
https://qiita.com/tamura__246/items/366b5581c03dd74f4508

**Open WebUI [#z2f80f6b]
-Ollamaをwslにインストールして使う。ついでにwebブラウザでOllamaを表示させる #WSL - Qiita~
https://qiita.com/mkuwan/items/ff84679ed8308ae78979

**Chainlit [#mcd99ab0]
-Chainlitを試してみる #LangChain - Qiita~
https://qiita.com/taka_yayoi/items/3afeea6edb4f1eb022b4

-チャット UI を簡単に作れる「Chainlit」の紹介 ~ LangChain との統合 ~ #Python - Qiita~
https://qiita.com/skkzsh/items/17bff703dba27240ec90

**Ollama-ui [#l8d7482d]
-Windows版 Ollama と Ollama-ui を使ってPhi3-mini を試してみた #Windows,Ollama,Ollama-ui - Qiita~
https://qiita.com/programing_diy_kanrinin/items/24d0778a42ae0f24deae

**ChatKit [#jd7ba186]
https://www.eesel.ai/ja/blog/chatkit

トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS