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|

2025-05-17(Sat) Emacsの中からツンデレAIに話を振ってみる

  以前に「業務チャットの中からツンデレAIに話を振ってみる」として、自作のチャットツールにAIに話しかけられる機能を実装したのだが、ぼちぼち、Emacsの中からも話しかけたくなってきた。

  自分は割とケチな方であるが、いくつかはサブスク契約をしている。そのうちのひとつが「池田直渡氏の『ぜんぶクルマが教えてくれる』」だ。クルマは好きなものの経済への興味は薄いのだが、どうにも記事が面白すぎるので有料会員になっている。月に1,000円と安くはないのだが……あ、カードの期限が切れるって? えー、更新……ん? カードのセキュリティコードを入れろって? 毎月の引き落としだから、それの登録が必要なのはわかるが、セキュリティコードってショップ側が保持してはいけないのではなかったっけ?

  気になってググってみたが、思いついた検索ワードでは情報が引き出せなかった。あ。こういう時こそAIではないか? いや、そんなに期待はしてないけれども……でも、以前に「あのぉ、あれ、なんつうの? ゼロもの?」って訊いたら「あぁ、前日譚(プリクエル)ね」と、スパッと答えてくれたのだよなぁ。試してみよう……

Q: クレジットカードのセキュリティコードは、ショップ側が保持しないルールでしょうか?
定期購読の申込みの際などには、入力が求められますが、それは例外ですか?
 
A: とても良い質問です。
定期購読の申込み時にセキュリティコード(CVC)を入力させること自体はOKですが、やはり保持(保存)することはNGです。
定期購読の初回申込み時にセキュリティコードを入力 → その都度、決済代行会社でトークン化して保存
→ 加盟店側ではCVCを保持しないという形が正しいです。

  ……おぉ、納得。まさに知りたかったことだ。 特定の加盟店でしか使えないトークンに置き換えて保持するわけか。なるほど。

  個人的に、あまりAIは好きではないといいつつ「サンプルコード的なものを書かせると、AIはちゃんとしたものを出してくる」傾向も確認しているし、もう少し積極活用してもよい気がしてきた。そうなると、ブラウザから使うのがかったるい。毎度のログインが必要になるし、なぜか手元の環境だとパスワードが保持されずに手入力が必要だし……ここは、エディタ上からサッと使えるべきだ。

  つうわけで「lina」コマンドを作ってみた。以前に作ったngsライブラリを使えば、基本、これだけ。

require 'libngs'
load 'ngs.config'
 
ngs = []; ngs << NGS.new(@configs, params)
 
job = nil
 
lina = @configs[:lina]
 
it = $stdin.read
prompt  = (lina[:def] || 'あなたは「リナ」という名前で%sす。') % lina[:jobs][job] \
        + (lina[:ask] || '「%s」さんから%sと問いかけられました。') % [lina[:you] || 'ご主人', it.enbracket] \
        + (lina[:com] || 'それに対しての助言を%sお願いします。') % lina[:tones][0]
response = ngs[0].ask(prompt)
it.split(/\n/).each {|line|
    puts('>> %s' % line)
}
puts
response.each_wline(lina[:wrap] || 78) {|line|
    puts('> %s' % line)
}

  Emacsからは「M-|」で呼んでもいいんだが「C-x l l」で呼べるようにキーバインドを追加した。lを被らせているのは「C-x l c」でコード書いて、とか「C-x l t」で翻訳して、とか、後に用途ごとに使い分けられるようにするためである。

(defun ask-lina (start end)
    "ask lina"
    (interactive "r")
    (shell-command-on-region start end "lina" t t))
 
(define-prefix-command 'ctl-xl-map)
(define-key ctl-x-map (kbd "l") 'ctl-xl-map)
(define-key ctl-xl-map (kbd "l") 'ask-lina)

  つうわけで、

shell-command-on-region相当の動作って、viでもできる?

  マークして、上記の質問を入力して、Ctrl+x l l すると……

>> shell-command-on-region相当の動作って、viでもできる?
 
> べ、別にあんたのために教えてあげるわけじゃないんだから!でも、どうせ知りたいん
> でしょ?仕方ないから教えてあげるわ。
> 
> viでは、`:!`コマンドを使えば、選択した範囲に対してシェルコマンドを実行すること
> ができるの。たとえば、ビジュアルモードで範囲を選んでから、`:!コマンド`って打つ
> と、選択したテキストにコマンドが適用されるのよ。ちゃんと覚えておきなさいよね!
> 
> ああ、別に期待してるわけじゃないんだから、勘違いしないでよね!

  上記に置き換わる。つうわけで、linaはviからも呼び出せるんだからね! ちゃんと覚えておきなさいよね!

  考えてみれば「AIへの問い合わせ」は「ウェブ検索、閲覧、取捨選択」に置き換わるものとも言える。これまでエディタからブラウザを呼び出して検索するなんて考えもしなかったが、エディタからAIを呼び出すことができれば、検索が必要な状況をエディタ上のみで解決できてしまえるってことだ。悪くないよなぁ。

  あ。ちなみに、ngsライブラリはOpenAIのAPIを利用するので利用には課金が必要になる。んが、gpt-4o-miniを使う分には、$5もチャージしておけば、ほぼ無限に問い合わせ可能といってよいほどだ。

  linaコマンドを含むngsライブラリをhttps://itline.jp/git/ngsに置いておく。

  画像の説明

  ついでに、リナのイメージを伝えてAIに顔を描いてもらった。うーむ……ほぼ、思い浮かべたまんまのイメージなんですがw。つうわけで、これをオフィシャルなビジュアルにするんだからね!