SVX日記

2004|04|05|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|08|09|10|11|12|
2011|01|02|03|04|05|06|07|08|09|10|11|12|
2012|01|02|03|04|05|06|07|08|09|10|11|12|
2013|01|02|03|04|05|06|07|08|09|10|11|12|
2014|01|02|03|04|05|06|07|08|09|10|11|12|
2015|01|02|03|04|05|06|07|08|09|10|11|12|
2016|01|02|03|04|05|06|07|08|09|10|11|12|
2017|01|02|03|04|05|06|07|08|09|10|11|12|
2018|01|02|03|04|05|06|07|08|09|10|11|12|
2019|01|02|03|04|05|06|07|08|09|10|11|12|
2020|01|02|03|04|05|06|07|08|09|10|11|12|
2021|01|02|03|04|05|06|07|08|09|10|11|12|
2022|01|02|03|04|05|06|07|08|09|10|11|12|
2023|01|02|03|04|05|06|07|08|09|10|11|12|
2024|01|02|03|04|05|06|07|08|09|10|11|12|
2025|01|02|03|04|05|06|07|08|09|10|11|12|
2026|01|

2026-01-12(Mon) やりとり用の独自のRAG機構Xorag

  世は相変わらずAI流行りだ。徐々に世でのAIの立ち位置も落ち着いてきつつある。もはやインフラだな。テクニカルサポート業務を支援するために作ったXalebotも動き続けており、最近ではコッソリとAIの回答案をそのまんまお客に返したりもしている。まぁ、自分が内容を査閲して、返せそうなものだけ返しているので、別に省力化にはなっていないのだが、AIの精度もだいぶよくなってきているのも確かだ。

  しかし、ネット上に溢れているLinuxのノウハウがそのまま利用できる場合はともかく、そうでない場合にはあまり精度のよい回答が出てこないのが常。そういう場合に有効なのがRAGである。AIへの問い合わせの中に参考情報を付加することにより、その参考情報を踏まえた回答が期待できる。参考情報はあらかじめインデックスしておいて、問い合わせたい内容に近い情報を検索して与えるのだが、この検索にはベクトル検索が用いられることが多い。問い合わせたい内容のベクトルに近いベクトルを持つ文書を参考情報として付加するわけだ。ベクトル化はAI技術の根幹でもあり、親和性も高い。

  というようなRAG技術は、既に定番となっている手法ではあるが、具体的に中でどんな処理をしているかは不明である。ベクトル化に当たっては、ユーザがアップロードした文書を細切れにする必要があるが、どれくらいの粒度にしているのか。また、問い合わせの内容に近い文書を検索して与えるのはいいとして、近似の判断をどう行い、何件、どれくらいの量を与えているのか、などだ。

  しかし、そもそもレスポンス業務において、その方法は適切なのだろうか。アップロードする文書に回答部分が含まれるのは必須になるが、問い合わせ部分は含まれるべきなのか。改めて考えてみれば、相手からの問い合わせにマッチすべきは問い合わせ部分ではないのか。そう考えれば、回答部分をマッチ対象するのはおかしくはないのか。

  つまりこうあるべきではないのか。

1.顧客からの「今回の問い合わせ」を「今回の問い合わせベクトル」に変換
2.ベクトル検索により「今回の問い合わせベクトル」に近い「過去の問い合わせベクトル」がマッチ
3.その「過去の問い合わせ」に対する「過去の回答」を取り出す
4.「今回の問い合わせ」に「過去の回答」を参考情報としてAIに回答案を作らせる

  レスポンス業務ではなく、友人からのメールに例えるならこうだ。

1.友人からの「ドライブ行かない?」を「ドライブ行かない?ベクトル」に変換
2.ベクトル検索により「ドライブ行かない?ベクトル」に近い「ツーリング行かない?ベクトル」がマッチ
3.その「ツーリング行かない?」に対する回答である「どこへでも行くぜ」を取り出す
4.「ドライブ行かない?」に「どこへでも行くぜ」を参考情報としてAIに返事を作らせる

  逆に言うと、テクニカルサポート業務への自動回答案作成と、友人のメールに対する自動返信は同じ仕組みで実現できるってことだ。違いは、テクニカルサポート業務の場合、参考情報は過去のすべての回答が対象であるのに対し、友人の場合、参考情報は過去のその友人への返信に限る(限らない方法もあろうが)ってことくらいか。

  さて、どう実装するか。Xalebot-tmoの時は、xalebot.configの中に固定で口調を指定したり、全文検索から引っ張ってくるように指定できたりした。その延長としてこんなのを考えた。

・xalebot
 ↓メールスレッド ↑プロンプト
・xalebot.config
 ↓問い合わせ内容 ↑参考情報
・xorag_tmo
 ↓問い合わせベクトル ↑過去の回答
・pgvector
 ↓ベクトル検索 ↑近似ベクトル
・ベクトルDB

  xorag_tmoは、独立したスクリプトである。JSONで問い合わせ内容を受け、JSONで参考情報を返す。xalebot.configからは概ね以下のような感じで呼び出す。呼び出し方も、呼び出されるxorag_tmoも、Xalebotから見ると設定の一部である。RAG機能はXalebotの一部ではない、という実装だ。

# ベクトル DB 対応(問合せの経緯を DB 登録)
@configs[:xorag][:insertdb] = Proc.new {|mail_thread|
    call_xorag('insertdb', mail_thread)
}
 
# ベクトル DB 対応(問合せの経緯を元に DB から近似の回答事例を引く)
@configs[:prompt][:mk_a_proc] = Proc.new {|mail_thread|
    res = call_xorag('selectdb', mail_thread)
    obj = JSON.parse(res)
    max = 3; rels = []; obj['abstracts'].each {|abstract|
        (max -= 1) < 0 and break
        rels << abstract['abstract']['body']
    }
    <<MK_A % rels.join("\n\n").enbracket
それに対して返信内容の作成を%%sお願いします。
なお、以下の過去のメール内容を踏まえ、それに近い口調でお願いします。
%s
MK_A
}

  で、試してみる。試す友人は自作自演のヨシダくんである。Xalebot+Xoragとしては未知の友人だ。

おひさしぶり。ヨシダです。
 
先日、ようやくスイッチ2が手に入ったよ。なかなか抽選が当たらなくてまいった。
フルタは最近ゲームとかやってる? スイッチ2はもう持ってるのかな?
 
じゃまた。

  それに対して、Xalebotから以下のような自動応答が返された。この時点では未知の友人なので、参照すべき過去のメールがなく、AIとして一般的な友人に対する内容、口調になっている。

おひさしぶり、ヨシダ!
 
メールありがとう。スイッチ2、ついに手に入れたんだね!おめでとう!抽選大変だっ
たよね。フルタは最近あまりゲームをやってないけど、スイッチ2はまだ持ってないん
だ。ヨシダが楽しんでるのを聞くと、ちょっと欲しくなっちゃうな。
 
またゲームの話もしたいね!
 
じゃあまた!

  既に友人には自動応答メールが返っているが、差出人は「AI Furutanian」、件名には「【AI生成】」が付与されている。AIとはわからないようにメールすることも可能だが、現状はネタ扱いである。なので、加えて本当の返事を書いて出す。

おー、おひさ。ヨシダっち。元気そうでなにより。
 
> 先日、ようやくスイッチ2が手に入ったよ。なかなか抽選が当たらなくてまいった。
 
なかなかの争奪戦らしいね。ようやく最近は普通に買えるところもでてきたようだけど。
 
> フルタは最近ゲームとかやってる? スイッチ2はもう持ってるのかな?
 
どうも新しいゲームには興味なくてね。もっぱらレゲーで遊んでいるよ。
いまさらグラディウス2やってるんだが、1番装備だと全然クリアできなくて……。
歳で腕が落ちてないことを証明したくて始めたのに、おかしーなーw。
 
またねー。

  Xalebot+Xoragはこのメールをスルーせず、ベクトルDBに事例として格納するが、表立った動作はない。そこに自作自演のヨシダくんが以下のような返事をよこす。

返事ありがと。
 
>> 先日、ようやくスイッチ2が手に入ったよ。なかなか抽選が当たらなくてまいった。
> なかなかの争奪戦らしいね。ようやく最近は普通に買えるところもでてきたようだけど。
 
え、そうなの? こっちの方では見たことないけどな。
 
> どうも新しいゲームには興味なくてね。もっぱらレゲーで遊んでいるよ。
> いまさらグラディウス2やってるんだが、1番装備だと全然クリアできなくて……。
> 歳で腕が落ちてないことを証明したくて始めたのに、おかしーなーw。
 
グラディウス2か。フルタ好きだったよね。昔は結構スイスイクリアしてなかった?
でも、1番装備って……なんだっけ? そんなシステムあったっけ?

  それに対して、Xalebotから以下のような自動応答が返された。

おー、ヨシダっち。返事ありがとう!
 
そうだよ、グラディウス2は昔好きでね。1番装備は、確か最初のゲーム開始時に選ぶや
つなんだけど、実はけっこう難しいんだよ。慣れないと敵の弾幕にやられちゃってさ。
昔はずいぶんスイスイいけてたはずなんだけど、今は全然ダメだ。歳のせいかなぁ??
 でもちょっと面白いから続けてるよ。
 
他のレトロゲームもまた試してみようかなと思ってるけど、なかなか時間がないね。ヨ
シダっちもスイッチ2でいろいろ楽しんでるのかな?
 
またねー。

  早速、過去のメールを踏まえた内容になっている。「ヨシダっち」や「またねー」という呼びかけや「1番装備だが歳のせいかクリアできない」というあたりだ。

  しかし、もともとXalebotにはスレッド中の過去の経緯を加味する機能があるので、これらが必ずしもXoragの成果とは言い難い。なので、自作自演のヨシダくんに、別のスレッドでツーリングの話題についてメールしてもらう。

おひさしぶり。ヨシダです。
 
先日、カブでツーリングに行ったんだけど、もう寒くてダメだね。
そういえばフルタ、バイクを契約したとかいってなかった? いつ納車?
 
ほんじゃね。

  すると、Xalebotから以下のような自動応答が返される。

おー、ヨシダっち、おひさ! そうだね、寒くなってきたからツーリングもしんどいよ
ね。
 
俺はバイクの契約したよ!納車は来月の頭くらいかな。ようやく手に入るみたいで楽し
みだわ。
 
それより、ヨシダっちはやっぱりカブなのか? 寒いと風を受けるのが辛いよなー。で
も、やっぱりバイクでの景色は最高だよね。
 
今のところ、ゲームは相変わらずレゲーをやってて、最近はゼビウスにハマってるよ。
懐かしくて楽しい!
 
また遊びに行こうぜー!

  すると、当該スレッド中には出てきていない「ヨシダっち」という呼びかけや「レゲー」の話題が含まれた回答となった。ちょっと唐突だし「ゼビウス」がどこから出てきたかわからんが、まぁ「レゲー」の代表として出てきたのであろう。

  つうわけで、ほんの数回のやり取りでも、実際のメールの応答を学習し、オレっぽいメールが返せるようになっていることが確認できる。なかなかよいのではないだろうか。

  例によって、http://itline.jp/git/xalebotに置いておく。