chatterbotにtag付きの質問・回答データを登録する

chatterbotにtag付きの質問・回答データを登録する

(コストがかからない)お手軽なchatbotを作りたくて、pythonとchatterbotを使用してchatbotを作ってます。

chatterbotを起動すると自動的にdb.sqlite3が作成され、そこに以下のようなテーブルが作成されます。

sqlite> .tables statement tag tag_association

  • statement:学習データを管理するテーブル
  • tag:タグを管理するテーブル
  • tag_association:statementとtagを紐づけるテーブル
  • chatterbotの使い方は現在学習中なので、後日きちんとまとめるとして、今回は軽く詰んだ話。

    statementとtagを紐づけた学習データを登録したい

    最近は、生成AIパワーを活用してプログラムを作っています。

    で、先述の通り「statementとtagを紐づけた学習データを登録したい」とChatGPT4oに問いかけた結果返ってきたソースがこちら。

    input_statement = Statement(text=question, tags=tags) response_statement = Statement(text=answer, in_response_to=question, tags=tags) # selfとしているのは chatterbotを継承したclassであるため self.storage.create(input_statement) self.storage.create(response_statement)

    そのままは使えないかなと思いつつ、動かした結果、以下のようなエラーが出力された。

    2025-05-10 20:47:26,926 - ERROR - generate a search_text value 2025-05-10 20:47:26,949 - ERROR - Traceback (most recent call last): File "/Users/ユーザー名/Developer/GitHub/PythoProject/Miyabot/MbMiyabotEngine.py", line 316, in importCurpusForExcelFile self.storage.create(input_statement) File "/Users/ユーザー名/.pyenv/versions/3.12.9/lib/python3.12/site-packages/chatterbot/storage/sql_storage.py", line 228, in create raise Exception('generate a search_text value') Exception: generate a search_text value

    以降、Github Copilot君と格闘して出来上がったソースの最終系がこちら。

    # Statementオブジェクトを作成 input_statement = Statement( text=question, search_text=question, # 検索用テキストを設定 in_response_to=None, tags=tags ) response_statement = Statement( text=answer, search_text=answer, # 検索用テキストを設定 in_response_to=question, tags=tags ) # データベースに保存 self.storage.create(input_statement) self.storage.create(response_statement)

    しかし、エラーは解消せず。しかたなく、chatterbot.storageの中身を漁ることにしました。

    chatterbot.storage.createは「sql_storage.py」に実装されています。

    で、メソッドの引数をみたところ。。。

    def create( self, text, in_response_to=None, tags=None, search_text=None, search_in_response_to=None, **kwargs ):

    やだもー。求めている引数が全く違うじゃないですかー。生成AIたちは、createがstatement型のオブジェクトを求めていると言っていたのに対して、実際はstatementを作るためのバリューを求めていました。もーやだー。

    最終系のソースがこちら。

    # 基本のテキストを設定 search_text_question = question search_text_answer = answer if hasattr(self, 'nlp'): try: # spaCyによる解析を試みる doc_question = self.nlp(question) doc_answer = self.nlp(answer) # トークンを結合して検索用テキストを生成 search_text_question = ' '.join([token.text for token in doc_question if not token.is_space]) search_text_answer = ' '.join([token.text for token in doc_answer if not token.is_space]) except: # NLP処理に失敗した場合は元のテキストを使用 pass # データベースに保存 self.storage.create( text=question, in_response_to=None, tags=tags, search_text=search_text_question, search_in_response_to=None, **self.kwargs ) self.storage.create( text=answer, in_response_to=question, tags=tags, search_text=search_text_answer, search_in_response_to=search_text_question, **self.kwargs )

    まだ、カスタムは必要でしょうが、とりあえずエラーは吐かなくなりましたし、学習データにも登録されていることを確認できました。

    生成AIに頼り切るのはやはり危険だなと思い知らされまいた。最後は泥臭くライブラリをこじ開けていくのに勝るものあはりませんね。

    気づきの瞬間

    私:sql_storage の createはこのような機能だけど、その呼び出し方で合っているの? GitHub Copilot いいえ、現在の呼び出し方は間違っています。sql_storage.pyのcreateメソッドの定義を見ると、以下のように個別のパラメータを受け取る形になっています。

    2025/5/11修正

    Excelから作成した質疑データの登録結果をみていたころ、なんかいろいろたりなそうなところがありきになったのでちょっと改修しました。

    昨日バージョンで登録した学習データがこちら

       あいうえお|あいうえお||2025-05-10 12:31:16||||2895 まみむめも|ま み む め も||2025-05-10 12:31:16|あいうえお|あいうえお||2896

    見出しがないのが非常に恐縮ですが、conversation(3カラム目)とpersona(7カラム目)がありません。

    もっと違う登録方法ないのかなと思っていたところ、create_manyというstatementオブジェクトを内包したlist型編集で登録ができるメソッドがありました。(昨日も気づいたけど一旦スルーした)

    微改修した結果がこちら。

    # タグが登録されている場合は、1つ目をconversationとして使用する conversation:str = [] if tags: conversation = tags[0] else: conversation = [""] qkwargs:dict = {"search_text":search_text_question,"conversation":conversation,"persona":"Miyabot","tags":tags,"search_in_response_to":None} question_statement = Statement(question,in_response_to=None,**qkwargs) akwargs:dict = {"search_text":search_text_answer,"conversation":conversation,"persona":"Miyabot","tags":tags,"search_in_response_to":search_text_question} answer_statement = Statement(answer,question,**akwargs) statements:list = [question_statement, answer_statement] self.storage.create_many(statements)

    改修後のプログラムで実行した結果がこちら。

       あいうえお|あいうえお|ABC|2025-05-11 20:39:54.005044|||Miyabot|2995 まみむめも|ま み む め も|ABC|2025-05-11 20:39:54.005060|あいうえお|あいうえお|Miyabot|2996

    欠損データがなくなりましたが、まだまだ先はながそう。

      

    コメント

    このブログの人気の投稿

    【python】PySide6 におけるウィンドウとかダイアログボックス内のアイテムの自動調整

    脆弱性評価システムを作る〜CVSSとは〜

    dict型オブジェクトを内包するlistオブジェクトのコピー