0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Streamlitによるチャット機能の実装

Posted at

Streamlitによるチャット機能の実装はst.chat_input、st.chat_messageが中心になるといえるでしょう。

st.chat_input()

チャット入力を受け付けるためのウィジェットを表示。このウィジェットならではのパラメータは以下のようなものがあります。

パラメータ
accept_file ファイルの投稿を付けつけるかどうか。
False: 受け付けない。(デフォルト)
True:単一ファイルを受け付ける。
"multiple":複数ファイルを受け付ける。
"directory":指定したディレクトリ内のファイルを全て送信対象とする。
file_type 送信を許可するファイルの拡張子。リスト指定可能。許可されていない拡張子のファイルは、ウィジェットでの入力はできるもののサーバへは送信されない。

ファイルの投稿が可能かどうかは、ウィジェットの見た目で判別可能です。

返り値は以下の通り。

説明
None 何も送信していない場合。
文字列 accept_file=Falseで、メッセージを送信した場合。
dict-like object accept_file=False以外で、少なくともメッセージかファイルのいずれか一方を送信した場合。
メッセージは"text"属性(文字列)に、ファイルは"files"属性(UploadedFileのリスト)に保持される。

st.chat_message()

戻り値はチャット風のメッセージ表示をするためのコンテナ。
誤解を恐れずいうと「アバターと表示枠を提供してくれる機能」
表示する内容や見せ方については相応の実装が必要です。シンプルなものだと、以下のような感じになります。

st.chat_message( name='発信者名' ).write( 'メッセージ' )
パラメータ
name メッセージ発信者の名前。
avatar メッセージの左側に表示するアバター。指定なしの場合はnameで指定した値の頭文字。
絵文字やGoogle Icon (:material/icon_name: で指定)も可。

気を付けるべき点

st.chat_input()やst.chat_message()は履歴管理の仕組みを持っているわけではありません。従って、次のようなコードではHumanとAIのやり取りは直近1往復分しか表示されません。

import streamlit as st
from datetime import datetime

text = st.chat_input( "入力してください" )

if text :
    st.chat_message( "Human" ).write( text )

    with st.chat_message( "AI" ) :
        st.info( str( datetime.now() ) )
        st.write( f"Your input is '{text}'." )

過去のやり取りを記憶し一連のやり取りを表示するには、そのための実装が別途必要です。

例えばcache_resourceを活用して過去のやり取りを全て保持する方法が考えられます。
以下は、"AI"(という名前の何か)とやり取りしている風のチャット機能の実装例。
まあ、これだと、ユーザーがどんなメッセージを送っても"AI"はほぼ固定の回答しか返してこないわけですが。

import streamlit as st
import time

from datetime import datetime

class ChatMessage :
    def __init__( self, name:str, text:str, avatar=None ) :
        self.name = name
        self.text = text
        self.avatar = avatar

def toStreamText( text:str ) :
    for c in text :
        yield c
        time.sleep( 0.02 )

def display( cm:ChatMessage, is_stream=False ) :
    with st.chat_message( cm.name, avatar=cm.avatar ) :
        if is_stream :
            st.write_stream( toStreamText( cm.text ) )
        else :
            st.write( cm.text )

@st.cache_resource
def getChatHistory( name:str ) :
    return []
    
name = st.text_input( "Please input your name.", max_chars=10, width=150 )

history = None
if name :
    history = getChatHistory( name )

    for cm in history :
        display( cm )

text = st.chat_input( "Please ask me anything." )

if text :
    if history is None :
        history = getChatHistory( name )
    
    cm = ChatMessage( name, text, avatar='😀' )
    display( cm )
    history.append( cm )

    with st.spinner( "Please wait to answer from AI..." ) :
        time.sleep( 3 )
        cm = ChatMessage( 'AI', f'This message is generated by AI. {str(datetime.now())}' )
        display( cm, is_stream=True )
        history.append( cm )
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?