Prolog風に書くと業務課題を解く生成AI(理由は分からない)
ゴール
経験則の塊である製造・物流・事務部門は作業標準化が出来ない。隣の人が何をやってるのか分からない。プロセスがバラバラだから、自動化しても意味がない。これを少ない人数でもこなしたい。ただ、隣の人でも分からないくらいなので、外部の人間に分かる筈が無い。手の打ちようが無い。
===
「Prolog風」には条件がある。慣れれば簡単。
ダラダラ長く書いても、これが抜けてれば駄目。
①モデルの構築(環境)
②ルール
③初期値
④ゴール(停止条件)
具体例
普通に論理的な質問を生成AIに打つ。
違う問題でProlog風にするとこんな感じ。
生成AIは、ちゃんと答えを出す。
「論理的」とはちょっと違う。あくまでも「Prolog風」。
分からない人は、ダラダラ書いた結果でも動く筈?
ChatGPTが出たあたりから気になってLLM本を読んで読んで、1年間は使い途が思いつかない。1秒も触らなかった。
インターフェース2024/8月号で「生成AI」特集を読んで、ゲームを0から作るというのがあって驚いた。しかし…
何かが見えた気がしたので、触り始めてやっと1週間。
要旨
質問の回答はプロンプトエンジニアリングで可能。
問題解決の回答はプロンプトエンジニアリングでは不十分。
解きたい業務課題をどうやって表現したら良いか分からないからだ。
(プロンプトエンジニアリングの本を参考にしても、書けない)
しかしPrologを意識して生成AIに問題解決の質問をぶつけると、なんと普通に解いてしまうことが検証の結果わかる。
(プログラムコードを作るのではない)
逆に言うと、生成AIは論理プログラミングが出来る(みたい)。
よく挙げられる生成AIの使用法は多くの業種職種では当てはまらない。
しかし、こうすれば対象範囲を広げることができる。
※ChatGPT3.5でも、算数が弱いけど十分だった。人が直せばいい。
1. 解きたい問題が 知識を問う問題の場合(企画や営業部門などはこちらに近い)
確定的な問題とも言うべきか?
この場合は簡単。プロンプトエンジニアリングすら要らない。
Googleの要領。
質問がやや難しくなってくるとプロンプトエンジニアリングが必要。
クリエイティブな質問とかもOK。それはいい。どんどん使うべきだ。
例)日本の首都はどこ?(知識を問う問題)
2. 解きたい問題が 方法を問う問題の場合 (製造や物流や事務部門の課題はこちら)
例)チンパンジーにバナナを取らせる問題(方法を問う問題)
例)5Lと3Lから4Lを取り出す問題(既知で知識ベースで解答可能)
例)羊と狼とキャベツの問題(既知なので知識ベースで解答可能)
===
問題が未知の場合、プロンプトエンジニアリングでは解決が難しい。
特に、チンパンジーがバナナを取る問題では強化学習と同じで、環境を記述するのがとても難しい。どう書けばいいのか自分たちでも分からない。
私自身、生成AI本を読んでも読んでも一向に腑に落ちなかった。
「どうやって うちの仕事に使えばいいんだろう…
生成AIで議事録? それで幾ら儲かるだろう… 0円だな(笑)」
(こう考えると、一歩も進まない)
プロンプトエンジニアリングの教科書って、知識を問う問題の解決法がメインに書いてあり私はそんなのどうでもいいと思っていた。
確かに答えの精度は上がるんだろうけど。。。
===
もっと抽象的な問題になると、質問で使う言葉自体を新たに定義づけする必要も出てくる。これをプロンプトエンジニアリングといえばそうなんだろうけど、ちょっと意味が違う。RAG?技術的にはそうだけど、そういう表面的な事を言いたいのではない。
===
悩んでたら、同僚に「無茶な課題があったら振ってくれ」とお願いしていた私も悪いのだが、
「この業務課題、生成AIで解けませんか?」
と実に気軽に振られた。
明らかに不向きな、一種のスケジューリング問題である。
普通で考えたらそれは機械学習か、IF文の嵐で解決する問題だ。
無理無理と思いながら一晩寝ると、
何故か普通に生成AIでそうした問題が書けるようになっていた。
気のせいだと思い、色々と試すとスラスラ書けてしまう。
まだ答えの精度が悪いのは確かで、それはプロンプトエンジニアリングで解決できる。
しかし問題はそこではなく、何かを乗り越えた気がした。
===
例えば、こんな”ゲーム”はどんなGoogleさんの知識にも無いだろう。
これ、生成AIが解いて当たり前じゃないんですよ?
LLMの本を読んだけど、どうして解いてくれるのか私は理解できない。
Pythonのコードを書いて解くのならまだわかる。でも違うのだもの。
(最適化問題を質問すると生成AIはPythonを自ら動かし答えを出す)
生成AIに質問してみたけど、うーん… ブラックボックスじゃん。
ディープラーニングの学習結果だから誰にも分からないってことか。
===
疑り深いので、「Pythonで計算してください」とお願いしたら、答えは同じだけど全く違う表示(ランダム性ではなく)になった。
「Pythonで計算しています」と出る。
つまり、普通に計算する時はPythonは使っていないらしい。
そういえば、この質問をした時はギブアップして、途中でPythonを使って計算してた。
===
これは単なる組み合わせ問題に近いが、もっと複雑な業務問題も試してみたがChatGPT4.0はかなり良い精度で答えてきた。
そのうちの一つは、ExcelマクロとPythonで試行錯誤しながら1ヶ月かけてようやくテスト版を作った問題だった。あっさりと解いてきたので、椅子から仰け反った。繰り返すが、プログラムのコードを書いてくれたのではなく、問題を直接に解いてきた。
===
仮に、単なる組み合わせ問題で総ての組み合わせを試したんでも別にいい。
答えをよく見ると。これ最適値じゃない。別に良いのだ。
業務の世界では時間を掛けて最適値を出すよりは、今、まぁまぁの答えが欲しい。Excelのソルバーとかで組むと奴は延々と総ての組み合わせを探して最も良い答えを探してくれちゃうので、それをいい加減に済ませるのが逆に難しい。こういう、ヒューリスティック的な解はむしろありがたい。
組み合わせ爆発を起こすのなら、その時はPythonのコードを書いてもらって枝刈りする。業務を大きく捉えると大変になるけど、意外と各個の抱える問題は小さく部品分けするとそんなに大きな問題で無いことが多い。
これは組み合わせ最適化問題というジャンルで、それはPrologではない別の世界がある。これはむしろ私の本来の得意分野なので、別の書き方で生成AIに解いてもらう。(これは未検証だしまた後日。そうか、そうするとこれからはPythonコードも書いてないような論文も、ガンガン読むべきなのか… ハードル上がったな)
〈まだ全然わからないんだけど〉
おそらく、私は35年前に習ったPrologの文法を使って制約論理で生成AIに解いて欲しい問題を書いていた気がする。すると、確かにスラスラと書けてしまう。
実際にはPrologで書いてる訳じゃなくて、頭の中でPrologで書いて、それを日本語にして生成AIに書いているのだ。
Prologのコードを書くのはかなりぶっ飛んだ発想が必要で、デバッグも一筋縄ではいかない。だから私はPrologをわざわざ使う気は無いけれど、この方法に従えば目の前の課題をスラスラと生成AIで記述できてしまうのも確かだった。(今日はずっとそれをやってた)
最適化問題でなくて良くて、私はてっとり早く答えが欲しいのだ。
過去の学習が必要なものは機械学習にやらせればいい。でもそれだと誰でもは出来ない。
今日、実際にProlog風でない場合(ダラダラ書いた長文)でも動くだろうと思って試してみたら、何とかなりますね。実際には「ダラダラ👉要約👉勝手にProlog風になる」という過程を踏みましたが。
===
論理プログラミングが書ける人は、生成AIに普通にどんな問題でも書けるんではないかなぁ。
また、色々と検証していきたい。今日色々と試したが
・論理プログラミングが可能。 (LP)
・制約論理プログラミングすらも可能。(CLP)
制約論理プログラミングは、最適化計算に比べると単なる数式では扱いにくい問題も可能な点が異なる。それは当たり前でPrologは命題論理だけではなく、述語論理も扱えてしまうのだ。
※生成AIにPrologのコードを書かせて実行するのではなく、
生成AIにProlog風に書けば問題を解いてしまうのだ。。。
Transformerってそんな機能、無い筈なんだけどなぁ。。。
===
特に、制約論理プログラミングやMathematicaの記号計算の様に、数値が未確定なままで変数を扱っているのを見つけて驚愕した。算数は弱いくせに、こんなことが出来るとは。
<なぜこれを思いついたかと言うと>
ここ一年で考えたわけじゃない。何十年の試行錯誤…
だからこそ、次の人(居るのか?)には苦労して欲しくない。
<頭が良い人たちにお願い>
プロンプトエンジニアリングではなく、それの論理プログラミング版みたいな概念があるはず。そして、現状世界を箱庭として見るモデリングのテクニック。それを分かりやすく本にしてくれたら、買って読むぞ。1万円でも。
この方法でも、現実世界の問題をProlog風に記述するというのは、まだまだ敷居が高い。そこを崩す方法=モデリングをどうすればいいか。
私は18歳位からPrologを触ってきて、Prologをデバッグした時にその動きに感動して以来 思考方法をProlog風にしてきているのでProlog風に考えない方法が分からないのだ。
===
Prologで現実世界の問題を記述することをモデリングと言うので、本来はこの工程を自動化したいのだ。
<おまけ>
この話をしてみたら
製造系の人:うーん、と顔をしかめる。
技術系の人:「面白い!」と言う。
(こんな汎用的な無料ツールは無いのを知ってる)
営業系の人:え、そんなの当たり前じゃん!と明るく答える。
👉そーなんだよ、当たり前なんだよ!
===
試しに、この問題を生成AIにPrologで書かせてみよう。
あなたは作業管理者です。
仕事1は9時間かかり、AさんとBさんとCさんができます。
仕事2は3時間かかり、BさんとCさんができます。
仕事3は4時間かかり、AさんとCさんができます。
Aさん、Bさん、Cさんの上限を9時間とします。
仕事1と仕事2と仕事3を終える事が条件です。
どのように作業を振り分ければ、Aさん、Bさん、Cさんのうち2人でこなせますか?
いや、ここまできちんとは自力では3日でも書けないな(笑)
でも、上の日本語とほぼ1対1でコードが対応している事が分かる。
ルールだけ書けば、これで動いちゃうのがPrologの不思議。
% 作業時間の定義
job(job1, 9, [a, b, c]).
job(job2, 3, [b, c]).
job(job3, 4, [a, c]).
% 作業者の上限時間
limit(a, 9).
limit(b, 9).
limit(c, 9).
% 作業の割り振りを確認
can_complete_jobs([W1, W2]) :-
% 各作業者の初期時間
limit(W1, Limit1), Limit1 >= 0,
limit(W2, Limit2), Limit2 >= 0,
W1 \= W2,
job(Job1, Time1, Workers1), member(W1, Workers1), NewLimit1 is Limit1 - Time1, NewLimit1 >= 0,
job(Job2, Time2, Workers2), member(W2, Workers2), NewLimit2 is Limit2 - Time2, NewLimit2 >= 0,
job(Job3, Time3, Workers3), (member(W1, Workers3), NewLimit3 is NewLimit1 - Time3, NewLimit3 >= 0; member(W2, Workers3), NewLimit4 is NewLimit2 - Time3, NewLimit4 >= 0).
% 作業者の組み合わせを生成
worker_combination(W1, W2) :-
limit(W1, _),
limit(W2, _),
W1 \= W2.
% すべての作業者の組み合わせについて確認
find_solution :-
worker_combination(W1, W2),
can_complete_jobs([W1, W2]),
format('Jobs can be completed by workers: ~w and ~w~n', [W1, W2]),
fail.
% プログラムの開始
:- find_solution.
<さらにおまけ 直接解けなくても良い>
強化学習、もう1年以上勉強しているけど。与えられた問題に対してどうやって書き始めればいいのか全然わからないので放置!(読むことは出来る)
例えば、一般的な倉庫の運用問題。こんなの、作業者にヒアリングしなくても想像で誰でも書ける。実際はもっと難しい。
もう、流石にProlog風は無理なので、普通に書いてみた。
生成AIに(自分が知らない)Pythonの強化学習でサンプルコードを書いてもらう。これは普通の発想で、よく市販本に書いてある方法。
===
参ったなぁ、今まではPythonコードが載ってないからと読まなかった技術書も全部読んでいかないとならないのか… うーん
===
チンパンジーとバナナの問題を試しに書いてもらった。
ここまで抽象的な問題をPrologに落とすのは相当に難しい…
ひょっとすると、モデリングも既にできるのか…??
凄いな… 人間が油断すると馬鹿になるな。
そうか、こういう風に組むのか。
こういう問題はPythonでも書けるんだろうけど、面白くない。
これこそ、Prologの強みだ。
Prologは探索方法は記述しない。深さ優先探索だから効率は悪いけど。
あなたPrologが得意な論理学者です。
以下の環境をPrologで書き、解いてください。
環境:
チンパンジーがいます。
チンパンジーはバナナが好物です。
天井からバナナがぶら下がっています。
チンパンジーは届きません。
チンパンジーの周りには、箱が幾つかあります。
どうやら、箱を積み重ねて、その上に乗ればバナナに届きそうです。
👉(下記はChatGPTの言葉そのまま)
以下は、Prologを使ってチンパンジーがバナナに届くためのシナリオを表現し、解決するコードです。
まず、環境を定義します。
% チンパンジーとバナナの状態を定義
:- dynamic(at/2).
% 初期状態
initial_state :-
assert(at(chimpanzee, ground)),
assert(at(banana, ceiling)),
assert(at(box, ground)).
% 状態の変更
move(chimpanzee, ground, box) :-
retract(at(chimpanzee, ground)),
assert(at(chimpanzee, box)).
stack(box) :-
retract(at(box, ground)),
assert(at(box, stack)).
% チンパンジーがバナナに届くかどうかを確認するルール
can_reach_banana :-
at(chimpanzee, stack),
at(banana, ceiling).
% 行動シーケンスを定義
plan :-
initial_state,
move(chimpanzee, ground, box),
stack(box),
move(chimpanzee, box, stack),
(can_reach_banana -> write('チンパンジーはバナナに届きました'); write('チンパンジーはバナナに届きません')).
このPrologプログラムは以下の手順で動作します。
初期状態を定義します。
チンパンジーが地面から箱に移動します。
箱を積み重ねます。
チンパンジーが箱の上に移動します。
チンパンジーがバナナに届くかどうかを確認します。
以下のようにプログラムを実行することで、結果を確認できます。
?- plan.
このプログラムを実行すると、チンパンジーがバナナに届くかどうかが表示されます。