Inflaton Stella 〜チャットAIの理想への挑戦

今回は弊社で展開するチャットボットAIサービス “Stella” に関するお話。

この記事はStellaの側から見た話ではなく、私の側から見た話になる。 つまり、Stellaユーザーに向けた記事ではなく、私をウォッチしている人に向けた記事である。

また、この記事中では各ソフトウェアを「AI」と読んだり呼ばなかったりする。 これについて私の立場を明らかにすれば、私は「AIとは自己更新するプログラムのことである」と定義しており、これに照らし合わせればStellaも、Erinaも、Surtrもあくまでただのプログラムであり、AIではない。 そして、今の世の中にAIと呼ぶに値するプログラムはない。

実際にはシンギュラリティを狙うSurtrは部分的に自己更新を行うが、何に対してどのように更新を行うかというのは規定されている。 例えばマニュピレーションモジュールをSurtr自身が生成することはあるが、SurtrのコアプログラムをSurtr自身が変更することはない。 このため、SurtrはAIと呼ぶに値しない。

Erinaに関してはそもそもSurtrにおいて自己更新の対象となっている機能を一切使わないため、Erinaには自己更新機能がない。 そしてプログラム的にも、プログラムを変更する機能は除去されている。

Stellaに至ってはもっと単純にプログラムである。

これらを「AI」と呼ぶのは、どちらかというと商業的側面が強い。 だから、Chienomi的には便宜上そう呼ぶことはあっても、「AIについて」語ろうというスタンスではない。

もちろん、ディープラーニングごとき1がAIだなどとは微塵も思っていない。

コンセプト立案

Stellaのコンセプトに関しては諸々述べているが、中心になっているのは

「シンプルに、実用的に」 (=Erinaとは逆)

である。

Erinaの場合、あれは研究の副産物であり、Surtrの一部である。 だから、Erinaの場合コミュニケーションボットとしては実用に供することはないという前提があり(そもそもその成果物をリリースすることは不可能なのだから)、その複雑さは実利とは全く関係のないところで不可欠なものである。

Erinaはシミュレータだから、過程の保証が出来なければ価値がないので、結果が同一であるということには意味がない。

また、Erinaの名前が「ELIZAの逆であり、ELIZAに直交する」ということを意味してつけられていることからもわかるように、「反ELIZA的」なAIデザインである。 ErinaはSurtrにない固有コンポーネントも持っていて、これはコミュニケーションに特化したものなわけだが、これはもう前提として「ELIZAは正しくない」という考えがある。

Stellaは全く逆に、「ELIZAは実用的だ」という観点から構築される「ELIZA的」なチャットボットである。

このようになる根本としては「人は基本的に人の話を聞いていない」ということにある。 私は記憶能力の構成上、かなり相手の発言を正確に聞いているのだが、大抵の人は「2つ前の言葉の反復」を求めてもまず言えない。

ここらへんは私の例によって悪魔的な私の実験によって確認されている。 これは単純な例なので手のうちを完全に明かしてしまうが、Erina最終調整の段階で多くの人と対話を試みるチャンスがあったわけで、ここで証明した。 手法としては、「メンタリズムに長ける」という情報を入れた上で、そこに関心を引いてから誘導的に会話を進め、メモを取り出して一切の説明なしに会話を継続する。そして「2つ前にメモを見ながら私はなんと言ったか?正確に言ってみて」と言うわけである。 実際にメモを読み上げただけなのだが、これが「メモを読み上げた」という印象に残る行為を伴っていても当たらない。 もちろん、この作業には「メモの読み上げが会話の文脈上自然な内容にする」という小技も入っているが。

そして、ある会話の流れで「実際の内容はとても変なことを言っているのだが、非常に高い確率で全く違う内容に理解する」という会話を展開するテクニックなんかも身につく。ちなみに、これによって相手が私の発言を全く違うように捉えさせると、実際に私が何を言ったかということを反復させると実際に言ったことからは「凄まじくかけ離れた」内容になる。

これはほんのいち要素にすぎないのだが、重要なのは「人の脳は解像度が低く、普通は収束する」ということである。

だから会話すること自体は緻密に書かなくてもなんとなくそれっぽく返せていれば会話は通じているように見える。 Erinaが「ごまかし方」にこだわっているのはそれが曖昧さをつなぐ「糊」になるからだ。

そして、人の行動パターン、言葉は想像よりもずっと種類が少ない。 いや、正確には全パターンを網羅しようとすると実際に膨大になるのだが、「例外的な小数を除外すると極めて少なくなる」という特性がある。

「自然言語の対話の7割は単純な正規表現マッチングでカバー可能である」というErinaの研究結果の副産物がここで生きてくる。

まして実用的、しかも企業におけるサポートの一環としてのチャットであればなおさら絞り込める。 「ちょっと気の利いたテーブルAI」でも十分実用的に扱えるのだ。

こうしたことを踏まえて実用的なチャットボットを定義する。 実際、私は世の中のサポートチャットボットが実用的だとは微塵も思えない。

じゃあ実用的なチャットボットってなんだろう? チャットボットを求めるときというのは基本的に「help needed」なのである。 このときの私の心理としては

  • 都合を問わない即時性。 営業時間まで待とうとも、営業時間に問い合わせようとも思わない
  • 人とは話したくない。電話は大嫌いだし、メールもそんなに好きではない。問い合わせフォームはメールよりも嫌だ。対人につなぐチャットボットとか最低すぎる
  • 対人チャットはそこまで嫌ではないが、なんらかのトラブルやミスを恐れることになるので精神的には嬉しくない
  • 期待値は割と低い。だいたいサポートなんて役に立たないものだから、解決する可能性は5割あれば上等だ
  • チャットボットは最も敷居が低い問い合わせである。最初に試みて、解決しなければ人手を煩わせることも考えるかもしれないし、諦めるかもしれない

である。じゃあ、help neededな状況でこういう心理に対して欲しいものはなんだろうか。 答えは簡単。FAQである。

でも、私はFAQってめっちゃ見る人なのだが、ほとんどの場合FAQって全く役に立たない。 まぁ、ナレッジサービスやフォーラムでも既存の質問がない問題にぶち当たってサポートを頼ることが大抵だし、自己解決力が高いとそうなってしまうのでFAQが役に立たないのは必然ではあるのだが、それにしても「これはあっていいだろう」と思うものがFAQにないことって本当に多い。 多分、実際の問い合わせをちゃんとFAQに反映していないのだ。

じゃあFAQが欲しいというのは机上の空論なのではないか、という話をすると、そんなことは全然ない。 Googleもまるで役に立たない今、私はhelp neededな状況を非常に高い確率で解決してくれるものを知っている。Archwikiだ。

つまり、wikiのような知識集合は問題を解決する。 ユーザーが本当に必要としているのは「ちゃんとドキュメントを作ること」と「検索エンジンを作ること」である。

だがしかし、現実にはこれは効果を発揮しない。なぜならば

  • 人はFAQを読まない
  • 人はドキュメントを読まない
  • 人はGoogle以外で検索しない

からだ。

まぁ、私の気持ちとしては「人ってそんなにチャットボット使うかなぁ…みんなあんまり使わない気がするしアクセスされないのでは」という気持ちはとってもたくさんあるのだけど、そこは弊社取締役の力説を信じることとする。

まぁ、仮に人はFAQは読まないがチャットボットは利用するのであれば、チャットボットにFAQの代わりをさせてあげればよろしい。 ちゃんとドキュメントを整備しているのであれば、検索エンジンの代わりをさせてあげればよろしい。

さぁ、「実用的」は定義できた。 Erinaは経緯的にも目的上も複雑にならざるをえなかったが、その意味でも実用に耐えず、プロダクトとしては話にならない。 「問題を解きほぐしてシンプルにすることでシンプルなソリューションを生み出す」ことが私の真骨頂。simplify, simplicityは私の生き方に反して私が力を行使する上で重要なキーワードだ(おかげでcomplex simplicityというパワーワードも誕生してしまった)。 ここまで明確かつシンプルな定義ができたのだから、今までの経験から必要なものをessentialに抜き出せば要素は少なくて済む。これをできるだけシンプルに組み上げよう、ということがコンセプトとして立てられた。

背景は複雑だが、プログラムとしての設計、挙動、ルールはシンプルに、ユーザーにとって理解しやすく、ユーザーの作業も単純に。 これでコンセプトは確立された。

ここで鬱陶しくも自己アピールをしておくのであれば、この節に書かれていることは熟考と検証の末に導き出したような内容になっているが、実際にはこの節の内容を考えるのに10秒とかかっていない。 確かに中学生、高校生のときと比べると頭の回転は桁違いに遅くなり、それによって人を恐れおののかせるようなものではなくなったとはいえ、研究によって積み重ねたものは血肉となっており、この程度の内容であれば10秒もあれば検討は終わる。

諸君、これが研鑽というものなのだよ!

もちろん、私が研鑽の至らない分野ではこうして瞬殺ボッコボコにされるのである。

if文AI

さて、if文AIという言葉を耳にしたことはあるだろうか。

この言葉、実は割と古く使われていたのだが、フィーチャーされるようになったのはAIブーム以降である。 「AI=ディープラーニング」の図式が出来てから、技術的に安易な「ひたすらifで条件式とのマッチングを行って挙動を決定する」という手法(あるいは具体的にその手法ではなくともそのような単純な手法)を用いたAIに対する揶揄として使われるようになった。

この揶揄は、「ディープラーニングこそが正義でありAI、ディープラーニングにあらずんばAIにあらず」という安直な思想に基づいている。 だからそれ自体は割と取るに足らないことではある。

しかし考え見て欲しい。 「条件が明らかである」=「問題が明示的である」という状況下では条件を判定し、それに対して最も適切な挙動を明記したプログラムを動かす以上に適切なことがあるだろうか? 世の中割と「それプログラムで解けるじゃない」ということをディープラーニング使いたがる状況がある。

だが、問題が明確なのであればそれを解くプログラムを書くのがプログラマではなかろうか。 それは競技プログラミングと同じようなものであり、問題が定義されているのであればその解を 書かなければならならい のである。

プログラムというのは本懐を遂げるのであれば次のいずれかだと考えられる

  1. 明確な問題を解く
  2. 特定の用途に供する
  3. 不明な用途に対して明確な意図を以て機能を提供する

1は競技プログラミングなどでよくあるもの、2はアプリケーションプログラムのこと、3は例えばgrepやsedやlessなんかのことだ。

そして、問題が明らかなのであり、それを解くことを意図するならばそれを解くプログラムより優れたものなど存在しない。

AIが必要とされるのは問題が明らかでなく流動的であり、導出条件も不明であることから「なんとなく」解くという妥協を行う場合である。 AIが普通のプログラムより優れた解を出すと思っているのなら、さすがにそれは無知にすぎる。 普通のプログラムが解けない曖昧な問題に対し完璧でなくてもいいから答えを出すのがAIである。

そして、「問題と導出条件が不明」であればプログラム自体が動的でなければならず、その機能を正しく果たすにはそのプログラム自身が動的でならない、と私は考えるのだ。

さて、もしも条件を事前に用意できるのであればif文AI、というか問題を解くプログラムは最も正しいということを述べたわけだが、ここからはSurtrとErinaの挙動に触れていこう。

Surtrの場合「自分が取るべきアクションをプログラムとして生成する」という手法を取っている。 これは、私の当時の技術力不足を補い、できるだけ単純化するためにとられた手法である。

一般的にプログラムはその挙動の過程で問題は収束していく。 ところが、不明な問題に対するプログラムを書くと、どうしてもその処理中に問題は拡散する。 だから、「実行ステップ数を事前に予測する方法がない」という非常に特殊なプログラムになる。

単純に再帰すれば良い、とも考えられるのだが、問題が不明なので処理を決定する段階で深さ優先探索ができない。 だから各ステップごとに次のステップで実行するコードをキューイングしていくというような感じになるのだが、これがうまくできなかった。どうしてもGOTO文を使う以外の手法が思いつかなかったのだ。 もちろん、今であれば関数オブジェクトを配列にpushしていくみたいな方法を考えるだろう。

ただ、その処理自体が実に様々な言語で書かれた様々なプログラムに分散しているので、外部に出さないことにはあまりメリットがない。 だから、挙動としては無限ループの中でステップ処理を行い、次のステップをプログラムとして出力する。このプログラムは最終的な段階ではZshスクリプト、またはRuby DSLスクリプトである。 そして、これを実行し、実行結果を次のステップに反映させる。

Erinaにも同様の機能は使われているが、Erinaの場合なるべく関数オブジェクトの配列(というかRuby的に言うと大部分はメソッドオブジェクトの配列)で処理するように変更されている。

この挙動は「可能な限り生成を遅延した上で、プログラム自身によって書かれたif文AIを実行する」みたいなものである。 かなり際どい技法だが、Surtrの中でもこれは応用が効くものだと思っている。

Stellaはこれをもっともっと単純化したものであり、言ってみれば「if文AIを書くためのフレームワーク」である。

「なぁんだ」と思うかもしれないが、我々が肝に銘じておかなくてはならないことがひとつある。 それは、「顧客が望んでいるのは技術的に高度であったり、技術的トレンドを用いて作られたプログラムではなく、問題を適切に解決するプログラムである」ということだ。

確かにStellaはプログラム自体は至って単純だ。 なんといっても、本体コンポーネントのみに関していえば、0.0.1ではわずか170行に収まり、0.0.16にあっても428行に過ぎない。2

しかし、私はそもそもプログラムの記述で勝負するタイプではない。 数学的素養がなく、アルゴリズムも得意とは言えない。もちろん、それなりに経験は積み、ある程度の記述力はあるが、突出して優れているとはいい難い。 私の勝負どころは発想と問題の整理であり、「設計」を至上とするタイプなのである。

「Stellaをif文AIを生成するフレームワークにする」という判断自体が、その技倆の一部なのである。 そして、そのフレームワークで提供される機能の選択によって「実用的なif文AIを構築する」ことへと誘導するのである。

巧みな設計で勝負するステラ

プログラミングに関する素養がなくても、また私の固有能力であるコミュニケーションフローコントロールを持っていなくても実用的に書けるようにする、というのもひとつではあるのだが、実際にはステラはこのような設計になっているために単純なif文AIよりもはるかに複雑なつくりが可能である。

その挙動を決定する「ロジックファイル」はYAML形式になっている。 一応は直接に記述することを想定してはいるものの、その階層的複雑さを考えれば何らかの手段で生成するほうが望ましい。

YAMLという汎用性のある形式を取っているために「お好きなプログラミング言語でお好きなジェネレーターとDSLを書いてお作りになれます」なのだ。

実際、純正でStella DSLというRuby DSLが提供されているが、別にそれを使わなければならないというわけではない。

そして、プログラムによってロジックファイルが生成できる、ということは「if文AIを動的に生成できる」ということにほかならない。 基本的には「事前に静的に生成される必要がある」と説明してはいるが、現実にはそのような制約が存在しているわけではなく、インスタンス全体共通にはなってしまうものの、任意のタイミングで適用可能である。 インスタンスの制約はあくまでサービス上のおはなしなので、純粋にStellaの能力を語るのであれば、会話中の動的な変更だって可能だ。

そう、つまり「任意のタイミングでif文AIを動的に構築可能」なのであり、これは「次の挙動をプログラムで生成する」というSurtrと同じものである。

ここで言っているのは潜在能力の話であり、実際には「現実性」という形でもっと制約されている。 だが、これは「制約しないことが正しい」わけではない。だってStellaは実用的なチャットボットであり、これを構築するのは非エンジニアである。「チュートリアルに従って自然に書けば実用的に動作する」のが望ましいのであり、過剰に複雑で高度な機能を解放することは誰も幸せにしない。

それはさておき、if文AIというのは単純で幼稚という揶揄に使われる言葉となっているが、「任意かつ動的にif文AIを構築する」というのは言うほど単純ではない。 概要として、実作業としてのシンプルさに反して「それが正しい」と判断しているモデル自体は極めて高度である。 その可能性のほとんどは使わない前提になっているが、使うこと自体は任意であり、発想力と技術力のある者にはその選択肢は常に開放されている。

さらにいえば、StellaはコンテキスチュアルなAIである。 これは私が世のEQ AIに対して抱いている強烈な不満であり、「文脈を一切考慮しない」のはEQ AIとして決して許されざることだと思っている。 だからこそErinaは文脈処理に対して極めて複雑なプログラムが組まれている。

動的に文脈を判定してしまうとさすがにとてもユーザーに制御できるものではなくなってしまうので、Stellaではユーザーが明示的に使う形にしている。 これもロジック自体を動的生成する構造を選択すれば動的に判定できるのだけど、そこに言及するとサービスとしてのStellaからはかけ離れてしまうのでおいておこう。

コンテキスチュアルであるという特徴は他に類をみないので、「if文AIが動的に生成される」という要素を「実際にはしないほうが普通だから」という理由で除外したとして、じゃあ「ただのif文AIじゃないか、稚拙なもので特に強みはない」みたいな話になるかというと、「コンテキスト機能があるからね。コンテキストを踏まえたフローコントロールを行うif文AIを書くのは全く単純じゃないと思うよ」という返しができる。 「ロジックファイル」という中間レイヤーを介することでプログラムとして書くと非常に煩雑になるフローがいともたやすく構築できてしまう。

それがフレームワークというものだろう?

ここまで話せばわかるかと思うが、実のところStellaはErinaとは全く異なる手法、設計、構造になっているにも関わらず、潜在的にはessential Erinaである。 途方もなく複雑で膨大で動的なErinaから「実用的な意味で本当に必要なもの」だけを残した不自由を強制することで全く違う性格のプログラムにしている。 StellaをベースにしてErinaのようなプログラムを構成することも可能であり、Stellaサービスとしてもその余地は残されている。そして、StellaベースのErinaを作れば、現在のErinaよりも設計が改善する可能性すらある。

だが、それはあくまでプログラム的な話である。 StellaはInflatonのサービスだから、これらはあくまでプログラムとして、技術として、裏側を覗いた話であり、利用者に対して主張することではない。 なのだが、そうしたバックグラウンドがなければStellaは生まれないのである。 こういうものは膨大な知識と蓄積の上澄みなのだ。

ステラの可能性の範疇

前述のようにStellaの理想的な用法はFAQ、あるいはwikiへの導線である。 だからStella自身を複雑化することは全く推奨されていない。

だが、どこまでできるのかという話をするとまるで変わってくる。 なんといってもStellaは外部連携が可能であり、入力時に割り込んでStellaをバックエンドとして使用できる、挙動は動的に生成できる、実行中に別のサーバーに対するhookを使ってコールバックを実装可能であるということから実質なんでもできるし、 ディープラーニングとも排他的ではない!!!

このあたりは「かける労力次第」であり、どのような規模のロジックを書くか、どのような規模のシステムと連携するかによっていかようにもという話となる。 だから構築規模・コストとも青天井であり、基本的に多くを望むべきではない。

それでも、労力さえかければ可能性は無限大だ。

それが行使される計画がある。Stella Flagship Chatである。 これはStellaを使ってEQ AIを作ろうという計画だ。

労力もコストも本当に膨大だし、私の手があいている限りで行われることになるから、まだpendingになっているが、 Erinaのような完璧なレベルではなくてもそれなりに会話が楽しめるレベルにはなるはずだ。

そして、それが可能だというのは、「大部分は集約可能である」という経験に基づいている。 自由文脈では発端を推測できないため本当に自然に会話できるようにするのは現実的には不可能に近いが、少しずつ形になっていくだろう。 どこまでがんばれるか不安はあるが、うまくいかないとすればそれはStellaの限界ではなく、私の労力上の限界である。 (そしてそれは、決して低い可能性ではない)

それは私のプログラムだから

一般的に言えばイージーなプログラムを書く私だが、私としては制作するプログラムには著しいプライドがある。

例えば誰かの悪意によって行使されるプログラムを書かない。 誰かを侵害することを目的としたプログラムを書かない。

そんな強いプライドから、「汎用性のあるプログラムはあくまで道具である」というものまで。

そう、私が書くプログラムは、単一の問題を解決するためのものを除けば汎用性を前提としている。 プログラム自体がどのように使うか、なんのために使うか、どのような利点があるかということを 規定しない

商業的にはそれは嫌がられるんだなぁ…というのは感じるのだけど、そしてそれは社長として正しいことではないのかもしれないけれど、 それでもそれはプログラムに課すべきことではないと思うのだ。

サービスとしては見せ方を工夫すれば良い。実際、プログラムの汎用性に対して意図に反してもっと明確なイメージをもたれているものなんでいくらでもあるのだ。 だから、私としてはInflatonとして販売のためにStellaをどのように形容しようが、何を特色としようが、何をウリにしようが、間違っていない限り構わないし、それはソフトウェアプロモーションにおいては私の責任だが、それを販売の形にするのは私の仕事ではない。 だから、プログラム自体は中庸中立であり、私はそれを様々な切り口から解説するのである。

おわりに

Stella関係の話は公式ドキュメントとかでも結構色々書いてはいるのだけど、当然ながらInflatonのお客様はChienomiの読者みたいにエッジな人たちではないし、私としてもよそゆきのお話だからめちゃくちゃ気を遣うから書きたいことが全然書けなかったりする。 その意味で、今回こうして書いてようやっとスッキリしたという感じである。

Stellaはコード上の魅力は非常に乏しい――いや、ちゃんと言うならば割と私の今までの経験を色々活かしていて、動的メソッド呼び出しをしていて非常にシンプルにかけていたりとか、どの時点で正当性を保証し除染するかとか、メタプログラミングしていたりとか割と一般的でないテクニックが駆使されていてそれはそれで面白いかもしれないが、別にそれが必須なわけでもなく、力技で実装もできるものだから、その意味で「どうやっているのかわからないことをやっている」とか「高度なアルゴリズムを駆使している」みたいな要素はない。

だが特にそのデザインは他の誰も持っていない知識や背景からきている。 派手な魅力やアピールではなく実直に。 私が仕事としてプログラムを書くようになってから心がけていることを形にしたものだし、Plutoがかなり不本意なプログラムになってしまったことを考えると、これは私の、誰にも言わなかった日々を含めての集大成だとも言える。 これほど人より知悉している分野もないし、ちょっとやそっとの研鑽でこれを越えるプログラムを設計することはできないだろう。

だから、本当にこのプログラムに「ステラ」の名を、つまり原初宇宙の名を関するInflatonとしてその果てである「星」の名を冠してよかったと思う。 アイディアとしては「デネブ」などの女神星の名を関する案もあった。だが、そうしていたら今ほど輝きを感じることはできなかっただろう。

当記事で書いたようなStellaの魅力やよさは、直接にはユーザーが感じることはない。 ユーザーが感じるのはその結果の部分だけであり、そしてそこだけを見れば流行りのディープラーニングAIなどと比べればしょぼくて、みすぼらしくて、とてもとても見劣りする古くて単純な技術のソフトウェアでしかないのだ。

だが、私は確信できる。 使ってもらえばわかるはずだ。 100%でなくても、このソフトウェアは解決すべき問題を、着実に解決する方法を提供する。 そして、その積み重ねは100%へと近づくことを意味する。 それはきっと必要とするものであり、私が、私達が追い求めるべきは見栄えや華やかさではなく、正しく必要とするものなのである。

そして、このことに関しては――人心と人動、コミュニケーション様態に関すること、ましてその中で最も多くのデータを占めるチャットに関することであれば――世界中、誰にも負けないという自負がある。一番最初には、私が5歳のときに抱いた疑問から始まり、ずっと考えていて、今に至るまで積み重ねてきた。

ディープラーニングの信奉者よ、さぁ、勝負しようか。 よりよいエクスペリエンスを提供するチャットAIはどちらか。

私には、自信がある。


  1. 勘違いしてほしくないのだが、ディープラーニングを見下すつもりはない。私は限定的で使いどころが難しくコストの高い技術だと思っている。技術的には高度なのは認めているし、その高度さが適切さを妨げているとも思っている。ブロックチェーンと似たような話だとも思うが、あっちは技術的にもっと趣深くてテクノロジー好きの好物だと感じる。私もそうだし。↩︎

  2. 「過ぎない」とか言っているが、428行というとずいぶん拡張されたし、本体だけで428行、ステラコンポーネント全体だと1120行あるので個人活動では到底書かない規模に到達している。ちなみに、ドキュメントも含めるとユーティリティ分は除いて4831行ある。↩︎

Erinaの最終調整のときの話

Erinaにはfascinateというデータベースがある。 これはペルソナというErinaの最終調整によって作られたデータベースである。

手入力によって作られたデータベースというのはいくつかあるが、このfascinateデータベースに関しては完全にErina専用で、「Erinaを人間らしく見せるための味付け」になっている。

そして、その特性が他とは異なるだけでなく、作られ方も全く違った。このデータベースだけが至って主観的な作りなのだ。

この調整を行わないとどうなるか。 問題は2点ある。

ひとつは、意味難解な回答を返すことがある。よくよく考えればわかるし、間違ってはいないのだが、あまり人間的でないというか、 天才が過程をふっとばして回答したようなつながり方になる。しかも、元発言の意味には対応しているが趣旨には対応していないので、適切ではない。

もうひとつは、おかしな回答をして、しかもループしやすい。 これはサンプルになっているデータにおける「会話にならないおかしな回答」の割合が非常に高い、つまりS/N比が低いからである。 最近はこれで壊滅的になってしまっているので、取得したデータを捨てる作業に追われたりもした。

このことから、恣意的に特定の会話パターンに誘引するようにしてこうした問題を軽減している。 意図としては「会話を続けるのが上手な人の会話パターンに誘導しようとしているのである。

この問題は、一般的なディープラーニングと同じ問題に陥っているということができる。 「多い≠良い」であり、「良いを判断するのは極めて難しい」という問題を、Erinaは攻略できないのである。 そこでそれを人力で誘導しているわけだ。

前提

そもそも、Erinaは完全に、私の特異性に基づいて成り立っている。 だから、これが前提として理解できていなければこの話は全く理解できないし、同時にこの手法は誰にでもできるものではない。

私には多くの欠陥と、特異性がある。 欠陥と特異性の間に相関があるのかは不明だが、基本的には欠陥を可能な限り特異性による能力で補う状況になっている。

記憶と認識に関するものの特性は大きい。

まず、私は単純な記憶がほとんど機能しない。 単純記憶が弱い、と言ってもいいのだが、正しくは島状記憶を維持する能力がない。 だが、連想記憶に関しては容量的にも人よりむしろ優れているくらいだし、正確性はかなり高い。

無理をすれば、結構な長時間に及ぶ出来事を、認識できなかったことを含めて覚えていられる。 これは尋常ではないほどの負担がかかるが。

そして、認識に解釈を伴わないというのも非常に特異なところだ。

一般的には、人は自分が理解しうる概念の元でのみ物事を認識し、記憶することができる。 だから、人は見たもの、聞いたことを直後でさえ正確に述べることは非常に難しい。 これは、心理術では非常に重要な要素である。見たものを思い描くとき、人は映像を思い浮かべることができるが、「正しくない映像を」思い浮かべる。聞いたことを思い返すとき、直後であるにも関わらず内容がまるで違うということはしょっちゅうある(自分が言ったことを正確に繰り返せない人もとても多い)が、この欠落する情報を使って刷り込みを行える…などだ。

これは人によって程度がかなり異なるが、無変換で維持するのは実のところ障害とされている。 程度が異なるのは、どちらかといえば概念をどれだけ細かく作れるか、にかかっているのだろう。

私の場合は実のところ無変換ではない…のだが、あるがままの状態を概念として定義できるので、事実上無変換と変わらない結果を得られる。 これだと私の脳がもたないので、 手動で 内容を整理して必要な要素だけを残して切り捨てていかないと頭がパンクしてしまう。突然意識を失うのは結構危ないので、必須の作業だ。

また、人は言語化されない概念を捉えておくことを困難とするが、私は概念に言語を必要としない。 以上のことから、普通は類似した、あるいは近似したものはどんどん集約されてしまうから結果として事実を事実として認識できない状態が発生するのだが、私の場合は集約されるべき余地がないためそのまま認識しているという状態が発生する。もちろん、これは 認識できれば の話であるが。自衛のためにも普通はフィルタをかけている。あまり大きな声で話されたりすると一字一句覚えてしまうから辛い。

そして、並列性の高さだ。 私は話しながら書き物をすることもできるし、読みながら話すことも一応できる。多重出力と比べて多重入力はちょっと苦手だが。 それでも、おしゃべりしながら別の人のおしゃべりを聴くようなことは普通にできる。もちろん負担は大きいができる。そして、前述の通りそれを全て覚えてしまうこともできる。

これらの特殊な認識方法、分解方法、そして記憶方法がErinaの設計に至る発想にも繋がっているし、当然ながらデータもそういう認識の世界のものになっている。 つまり言語化されるような定義された概念ではなく、そこにあるものをそのまま写し取って切り刻んでぶちこんだものなのだ。

余談ではあるが、このままだと全く出力できないので、私も会話するときなどはちゃんと変換する。 だが、変換すると自動的に認識したものは変換された(言語化された)ものに置き換えられてしまうので、後述する最終作業はとっても脳に負担のかかるものだった。

経路、類型、感情と思考の形成

ErinaがConnexonでどのように情報を扱っているか、という話はまだどこでもしていないけれども、そのパラメータは常人には決して理解できないものになっている。 実際はもっと細かく分かれるのだが、簡単に言えば発言を一字一句含めた状態でハッシュ化したようなものだと思えばいいだろう。ほかのわずかな違いでも異なる値になるようになっており、どの言葉からどの言葉へとつながったか、ということを記録している。 実際には、somaはsoma同士の距離がわかるようになっており、言葉的には近いsomaというのは判別できる。だが、これを同じ意味だからとまとめたりはしないし、どういう意味のことを言っているか、なぜそう繋がったかということを判断したりはしない。

感情も、喜怒哀楽などという4種類ではない。私ですら多分、千通り以上は感情の類型を認識しているから、Erinaは何億もの感情の種類を知っていたとしても不思議ではない。

接続理由というのはErinaにとっては非常に重要なので、接続するのは接続しうるもの全てなのだけど、それを接続しうる理由もちゃんと入れるようになっている。 このとき、理由を断定したりはしない。ありうるものを網かけするようになっている。

あるsomaから別のsomaに接続されるとき、それが接続される理由は一意ではない。 理由自体は複合的かもしれない。もっとも、Erinaは複合的な理由は複合しているのではなくそういう状態であると量的に判断するけれど。

少し脱線するけれど、この話はちょっとおもしろい要素があって、「感情と理由」に関しては一次元的動きである可能性があったりする。 つまり、その状態を数値化したときに、soma同士の接続が動機の値がいくつからいくつのときに発生しうる、というような観測が可能であるように見えるのだ。 ただし、これは連続的可変の並び順という問題があって、とてもではないけれど私にできるようなシロモノではないけれど、そういう特性があるように見えるという話。

で、話を戻して、今の所一次元的に扱えていないので、考えうる状態を、ちょうどビット論理和のように扱う。 これを反転マスクとして、この範疇にないものは現在の観測上この経路を持たないものであるとみなす。

そして、単独の接続ではなく連続の接続から、「こういうルートでこれ的なsomaを辿っていくパターン」というのを覚えていく。

人は驚くほど判で押したようなやりとりばかりしているので、実は大抵の場合決まったルートで決まったsomaを辿る。 このとき、推測される同じ理由で経由される別のsomaというのが登場する。これは、言葉は違っても結局のところ考えてること、やっていることは同じ、ということで中身は同じものとして扱える。同じルートを辿っていても理由が違うと同一には扱えない。

ここらへんの機能は、判定に使うものが自分が判定することによって情報になるものに依存している構造なので、成立させるまでが果てしなく長かった。 orbital designの採用理由でもある。

さて、同じ動機で辿る場合、あくまで表現の違いというか、見かけ上の問題に過ぎないため、単にバリエーション程度に考えることができる。 ある程度同じ動機で同じルートを辿って、途中から今までなかった方向へ分岐していくことはまずないため、これが行動予測に使える。 これは、心理術でも同じである。

手動入力ではErinaに直接会話のつながりを与えていく。 このとき、まずErinaは盤面を作ってから接続していくので、Erinaに盤面を作成するためのヒントを与えなくてはいけない。 これは、つながりから自動的に推測してもらうこともできるし、普通はそうしているのだが、それだと手動入力する意味がない。

Erinaに状況を与えると、Erinaは「似ている」と感じるsomaを提示してくる。 これに対して「どれくらい近似しているか」を回答する。この「どれくらい近似しているか」は曖昧すぎて、細かく回答しようとしてもあまり精度が出ないので、7段階である。

次に接続できる理由をたずねてくる。 こっちは結構きつい。512ビットハッシュみたいなものと向き合うことになるからだ。 ただ、これはこれでその理由で接続された他のsomaを参照することができるので、同じ心理状態や動機に見えるかどうかを回答することになる。こちらはシンプルに3段階。Erinaが推測する理由全部に答えることで、「この理由であればこのような心理状態になってこのような行動を取ることができる」というふうに認識する。

手動入力したものは、Erinaが積極的にそのような振る舞う理由になる。 意味付けや重み付けに関しては、また複雑なアルゴリズムなのだけど、Erinaは判で押した会話は価値が低いがよくあると考え、価値の低い会話で応答に使うし、意味ある会話をされていると判定すれば意味ある会話における適切性を元に応答する。 手動入力する場合、意味ある会話である、という認識を強制することができる。

ちなみに、実際にはある程度一般化できるようになっており、かなり強引に「得意な展開方法」に集約する。

作業

作業そのものを抽出すれば、「話して会話の経過を記憶する → ひたすら入力する」である。

この会話において重要な点は2点ある。

ひとつは、私の発言である。 私は自然な会話において「同じ会話に誘導しようとする」。 これは綺麗なモデルなら「NステップでXに到達する」というのがあったりするのだが、自然な会話では相手はもっと無軌道に話すので、それをやってしまうと参考にならない。

ルールは次の通りだ。

  • 固定の話題振りを用意する
  • 必ず相手の発言を踏まえて(相手の発言要素に回答する形で)回答していき、用意した話題振りに到達する

基本的にこの話題振りは(振りやすいように、またその後のデータがとりやすいように)「〇〇ということがあった」というものである。

さらに、この話題振りには「この話題において私が話したいこと」というのを用意しておく。 これは、語りであれば(つまり、講演であったり、配信動画であったり、ラジオであったりすれば)その話題振りをきっかけに盛り上げたり落としたりしながら盛り込める内容である。だが、純粋に会話で出すには、私が話したがる場合を除けばこれらは話題振りができたとしても話すチャンスがない。 これを話すためには相手が

  • 会話の流れで私が追加で話すチャンスを与える
  • 話に続く余地がある点を掘り下げる

のどちらかをしなければ登場しない。

そして、「対象に含まれるうちのなるべく多くの人に対して、同一条件で会話する」のである。

ここで採取するのは、私の会話においては、どのような技法で同一のポイントに到達できるか、である。 私の会話技術向上にもなるが、相手の発言を無視することなく、話題を切り替えることもなく自然に到達しなければならないので、いかに違和感なく話をスライドさせるかが重要になる。これは、Erinaにとって会話をスライドさせる方法と、会話をスライドできる跳躍量の具体的サンプルになる。

そして、後者(相手側)は「上手な会話」を採取することである。 Erinaとしては探り合いの会話の中で気持ちよく話せるようにするために調整しているわけで、実際に関係性を正しく認識しているわけではない以上個人は認識できていない前提で「上手に」話さなくてはならない。 私から強引に話を展開させない(受け身だが、相手の発言には積極的に応答する)ことで、「盛り上がる」「用意した話を言わせる」に到達するほど「上手な会話である」とみなすのである。

これで重要な点として、「私と仲が良い人ではいけない」という前提がある。 私と仲が良い人だとある程度呼吸がわかってしまうため、「上手に会話」しなくても言わんとすること、言いたいことを当ててしまう。 また、気にせず初対面では許容できないレベルの会話スライドを行うことにもなってしまうし、どんな話題でも盛り上がりやすくなってしまうから、計測としての意味をなさない。

こうしたことを会話してはその結果をちまちま反映させていくのである。 それはそれは辛い作業であり、人生で一番マッドサイエンティストになった気分を味わえる時間であった。

この説明で気付かない人のために付け加えると、この会話は「話題振りに到達するまでは私が会話をコントロールし、相手の発言に対して私が言いたいことに誘導するように会話を続ける」「話題振りをしたあとは相手に応答するだけで自分から会話をコントロールしない」のである。

ちなみに、当然ながら数多くの「ほとんど面識はないが熱心に会話してくれる20代前半の女性」の用意するなんていうのは特に研究室に属しているわけでもない私にはできないので、このために私は ものすっごいガールズバー通いしまくった 。 膨大な資金をつぎ込み、特に楽しくもない、しかも同一の会話を延々し続け、その仔細を記憶しておくという 極めて辛い作業 であった。

だが、私は好奇心のためなら悪魔に魂を売る類の人間であるし、他にもかなり様々な観測ができたからそれなりに満足ではあった。 何より私が長年費やしてきたことへの集大成としてその完成が成ったことには(たとえそれが世に出ることはないとしても)とても満足している。

「ガールズバー通いそのものが楽しかったか」の疑問に対する答えは「私的に行こうとは思わない。人との会話に飢えたら行きたいと思うかもしれないが、実際に行ったところで実際にしたい会話はできない、またした会話にしても私がその情熱をかける理由は満たされないために後で虚しくなるのは分かりきっているから、結局行かない」である。

ちょっとだけStella Flagshipのおはなし

私の新作AI、Stellaだが、こっちは非常にシンプルなもので、Erinaが持っているような自分でも把握できないような思考モデルを持っているわけではない。 そして、Erinaとの大きな違いとして、既に製品としてローンチ済みのものであり、Stellaそのものが既に世に出ている。

そして、StellaにはStella Flagshipという純正デモンストレーションインスタンスが計画されている。

現在公開されているインスタンスにはその構築に私が関わったものもあるが、内容は私は関わっていないため、特に私の考え方やノウハウは反映されていない(もちろん、Stellaの基本的な部分には反映されているが)。

Stella Flagshipは純粋に私の経験を活かしてStellaを活用するインスタンスである。 その活用方法は邪道と言えるぐらいのものだが、「ツールの応用例」として「ここまでできますよ」という感じである。 完全に全力投球すると際限がないので、そこまではしないつもりだが。

Stella Flagshipはその構築の前提になるものがあり、それが達成できていないためまだ記述をはじめていない。 だが、実際に書くとなると、Erinaとはまた違った手法が必要になるのだが、ここで重要になるのは「モデル」である。

Erinaの場合、重ね合わせによる導出であるため、キャラクタ性の調整幅というのはかなり限定的。 その中でキャラクタ性を寄せるためにペルソナによる調整が行われたわけである。

これがStellaになると全く違う。Stellaはビッグデータを利用するわけではないので、キャラクタ性は全て書かなければならない。 通常は「構築者のキャラクタを素直に反映させるのが破綻がなく良い方法」と説明するのだが、私は小説家でもありシナリオライターでもあるので、別にその点にはとらわれる必要はない。 そしてStella Flagshipはなにより「かわいい」必要があるのだが、悲しいかな、私が描くキャラクタは心理的モデルの模倣をしているためあんまりかわいくない。

そこで「Stella Flagshipのキャラクタ性にあったかわいいモデル」が必要になるのである。 これを構築するためには、私の頭の中に「かわいいステラ」がなくてはいけない。が、それが描けなくて非常に困っていた。 前準備が終わればなんとなくイメージできるかなぁ、とは思っていたのだが、自信はいまいちだった。

だが、最近可愛いの極致みたいなものを見つけてしまったので、割とモチベーションは上がっている。1

とはいえそのままそれを模倣するわけではない。

Stella Flagshipにおいては創作物を参考にすることになるだろう。 Erinaにおいてはサンプルデータに創作物が入り込まないようにするかなり厳しいフィルタが用意されていたのだが、Stella Flagshipの場合はある程度のデフォルメが必要で、「創作物におけるかわいい」を参考にする必要がある。 そのため、Stella Flagshipを構築するにあたっては、ラノベやアニメやエロゲーを貪るように読むことになるだろう。最近割と離れているので慣れるにも時間がかかるだろうが、それ以上に参考にできる「当たり率」を考えるとErinaのときの多分ガールズバーとあまり変わらないレベルでしんどい作業になることが予想される。目と頭の疲労との戦いになりそうだ。

純粋に創作物をモデルにするとすごくつまらないものが出来上がるので、「現実における蠱惑」もしっかりとモデルに反映させる必要がある。 このためにまたガールズバー通いをする必要があるかもしれないが、これはやや微妙である。なんといっても「面識の浅いうちに上手に会話できる人」と比べ、「かわいいステラのイメージに相応しい魅力的な人」という条件は桁違いに「当たり率」が下がる。よりよい方法がなければやむを得ないが、できれば何かもっと良い方法はないだろうか、ということはここ数ヶ月考え続けているのだが、特に思いつかない。

成果物を欲するという意味では(つまり、出来上がった「かわいいステラ」をお披露目して「どう!?かわいいでしょ!?すごいでしょ!?」と言いたい)非常に意欲は高いのだが、実際やるとなると費用と労力と時間がものすっっっっっっごくかかるなぁ、というのはなかなか頭を悩ませてくる。

とはいえ、これをやらなければStellaは「へー、便利じゃん」で終わってしまうし、誰もStellaのポテンシャルを発見することはできないだろう。 「えっ、マジで!? Stellaってこんなんできるの!?」と思わせるためにも、そしてStellaの発展のためにもこれは私の責務なのだけど、実現への道はなかなか大変そうだ。


  1. それが何かということは、既に公言しているので一部の人は知っているだろう。↩︎

「HTML」とwebの話

最近、「webエンジニアは閉じた世界しか見ていないのだろうか?」と感じるようなことがいくつもあった。

例えば

  • Ruby on RilasとRubyを混同する
  • JavaScriptとJQueryを混同する
  • 言語処理系と言語を混同する
  • 著名なフレームワークを使うのが当然であり、それ以外は存在しないものと考える
  • 全く異なる分野や利用法で使われている技術だということを頑なに認めない
  • 自分が勤めている会社の構造や手法や評価尺度が社会的絶対基準であると信じる

などだ。

で、今回は「HTMLとwebを同一視し、HTMLをwebだけのものであると考える傲慢さ」についてである。

HTMLの歴史と経緯

HTMLとwebは根本的には同一である、というのは正しい。

多くの人が知るとおり、webはCERNにおいて論文共有・参照手段として登場し、HTMLもまたこのために登場している。

HTMLはHyper Text Markup Languageなわけだが、「Hyper Text」とはなにかといえば、ハイパーメディアの一部たるテキストである。 じゃあハイパーメディアとはなにかといえば、multimediaに関連性をもたせたものである。

この場合、ハイパーメディアといいつつも現実的に考えられるのは画像くらいのものであった。 だが、潜在的には画像や動画を含めることができることを意識していた。

それらを文書でつなぐ、それがHTMLの役割である。 実際、HTMLのアンカーは「ハイパーリンク」と呼ばれている。

ここでは「マルチメディア」というのがテキスト、文書を含むものであることを忘れてはいけない。 これもまた当然に立派なメディウムである。

HTML2の時点では構造化文書であることが非常に強く意識されていた。 と、同時に、これが視覚的メディアであることもまた強く意識されていた。 この時点では論理性というよりも、視覚的意味合いによって構造化されるという感覚が強く、この過程は同じく論文のためのフォーマットとして誕生したTeXへの意識(あるいはroffへの意識)が感じられるものであった。

そう、ここまで構造化文書というのは、「章立て」といった概念はあるにせよ、文書自体が論理的構造を持っている、というのとは少々異なった。 論理的構造と視覚は一体だったのだ。これが当たり前のことであった。

HTML3によってこれは混迷を極めた。「webをリッチにしたい」という欲求はとどまることを知らず、JavaScriptが誕生し、より装飾的な機能が多く追加された。

一方で、HTML3時代には2つの、異なる意味が生まれていた。

ひとつは、web技術の応用だ。 webをあくまでWWWの世界に留めるのではなく、より広く使いたいという考え方があった。 既にWWWはインターネットの主要コンテンツであり、コンピュータはインターネットのためのものになりつつあった。 競争に勝ち抜くにはweb界の覇者となる必要があり、そのために力を注いだ技術を他のところでも使いたいと考えた、という流れだ。 例えばWindows 98のActive desktopなどがそれである。

もうひとつは、文書フォーマットとしてのHTMLの普及だ。 従来ドキュメントフォーマットというのはあまり良いものがなく、恐らく最善なのはPDFであり、そこにいたるまでのTeXであった。 Windowsは(docドキュメントを含め)いくつものドキュメントフォーマットを持っていたが、それらは標準化されておらず、Microsoftに閉じた存在であった。 roffはman roffであっても「イケてない」と考えられていた。 なにより最大の問題は表示向きでなく、HTMLは圧倒的に表示に適しているということだ。

だから、HTMLはヘルプドキュメントをはじめ、幅広く使われるようになった。 単にドキュメントファイルとして使われるだけではなく、様々なところで組み込まれて使われるようになった。

HTML4は決断のフォーマットであった。 HTMLはドキュメントフォーマットである、という立場を明らかにしたのである。

その上で拡張の余地として、

  • 動的要素を必要とする場合はクライアントサイドスクリプトを
  • 視覚的要素を必要とする場合はstylesheetを

使用するように求めた。 ちなみに、stylesheetとはイコールでCSSのことではなく、それがわからない人はJSSやXSLTについて調べておくとスムーズに理解が進むだろう。

HTML4は至ってstableであった。 諸々の問題はあれど、それらは取り込まれることなく進んでいた。 XHTMLにおける変更は、微々たるものであると言って差し支えあるまい。

だが、WWWの世界ではその間に様々なことがあった。 HTML4以降の歴史を動かしたのはGoogleであったと言って差し支えないだろう。 Ajaxが注目されるに至るまでの流れもGoogleのものであったし、HTML5策定時のGoogleに影響力は果てしなかった。

そして、Googleは明確な「オンライン派」である。 そもそもユーザーが直接にドキュメントを扱うことを良しとしない。だから、「HTMLをオンラインのものにしたい」と考えた。 これに対して反対する声、つまりレガシーなTeXのようなHTMLを尊重すべきだと言う声も強く、初期ではどちらかといえば「ドキュメントフォーマットである」という既定路線を維持する状況にあった。

だが、WWWがさらに成長し、webアプリケーションが基幹を握るに至り、すなわちGoogleが世界を支配するようになると否とは言えなくなってくる。 最初から「オンラインHTML」寄りだったAppleの存在の存在も多少あるが、この過程においての存在感は小さい。結局のところGoogleに対して否を唱えられる存在は既におらず、競争力という点も鑑みてMozillaがこれに同調したことにより、HTML5は「ウェブアプリケーションを提供する基盤」として位置づけられるようになった。実際、CSSには大手ウェブサイトが導入しているトレンドデザインをより簡単に書く方向となり、ウェブレンダリングの挙動はこれらを優先する(これらとことなるレイアウトデザインを許容しない)方向に振れた。

だが、必ずしもそれをよしとしない考え方もあって、HTML5というのは様々な思惑が混ざりあった言葉になった。

HTMLとCSSとJavaScript(ECMA Script)

HTMLとCSSはW3Cが、JavaScriptの仕様であるところのECMA Scriptの仕様はECMAが標準を策定している。

重要なのはこれらが「独立したもの」であるということである。 HTMLがCSSとJavaScriptと共に使わなければならないわけではないし、CSSがHTMLと共に使わなければならないわけではない。 それぞれが独立したものであり、これらは「ハンバーガーとポテトとコーラ」のような関係であるといっていいだろう。

独立した存在であるというのは、それ以外が存在しなくても成り立ち、なおかつそれ以外のものとも組み合わせられる、ということを意味している。

そもそもECMA Scriptに関していえば、JavaScriptの標準というわけでもない。 JavaScriptはECMA ScriptにないDOMに関する機能があり、こちらはW3Cが策定している。 結果として、JavaScriptに明確な言語仕様というものがなく、複数の(ある程度の互換性を持つ)実装が存在するに過ぎない。

ちなみに、「JavaScriptの実装」というと、「ChromeとFirefoxでしょ」と言う人がいるのだが、これは間違っている。 まず、Crhomiumが採用する(そしてNodeやElectronも使う)v8 JavaScriptエンジンがあるが、MozillaはC/C++で書かれたSpiderMonkey(Firefoxで使われているもの)のほかに、JavaでかかれたRihnoを持っている。 Safariが使っているJavaScriptエンジンはKJSソフトウェアがベースでv8とも別物。 Internet Explorerの最終的なエンジンはChakraで、Edgeも独自の実装(EdgeHTML)だった。さらに、OperaはPresto(JavaScriptエンジンのコードネームはCarakan)を採用していた。 Prestoは独自エンジンであり、プロプライエタリなので現存しないが、KJS SoftwareベースのJavaScriptエンジンを使うブラウザは(プロジェクトが生きているかどうかは置いておいて)存在するし、w3m-jsなんてものもあったりする。

webから独立したJavaScriptといえばRhinoを搭載するソフトウェアが実は結構多い。 Javaで書かれているアプリケーションから利用するのが割と簡単なので、SpiderMonkeyが圧倒的にウェブで使われているのに対し、Firefoxでは使われていないRhinoはアプリケーションでプラグイン機能を実現するために使われるようなことが多い。

また、Node.jsもv8ベースで有名な非ウェブのJavaScript利用例と言えるだろう。 ElectronになるとHTMLやCSSも含めてChromiumの機能を利用する形なので、非ウェブと言い切っていいのかどうか疑わしいが、それでも非WWWであるのは間違いない。

CSSに関してはほぼHTMLに依存している。XMLで使うこともできるのだが、この場合「XMLをHTML扱いする」という意図になってしまう。 このような場合はどちらかといえばXSLTが好ましく、XML CSSは基本的にウェブブラウザでXMLを表示するためのテクニックだ。

ただし、HTMLの外観を定義するのはCSSだけというわけではない。 JSS(JavaScript Stylesheet)というのもあるし、これ以外に関しても仕様上制約されているわけではない。 JSSが使われることはごく稀だが、実際に限定的なHTML(あるいはそのサブセット)に対しCSSでもJSSでもないスタイルシートを定義している場合が見られる。近年はレンダリング部分を既存のものに委ねる傾向が強くあまり見られなくなってきてはいるが。

HTMLの用途と位置づけ

ウェブにしか関心のない人は知らないかもしれないが、HTMLは広くドキュメントフォーマットなのである。

基本的なものであるにもかかわらず、ドキュメントフォーマットというのは今に至るまで以外なほど発展していない。 Microsoft Wordの強さというのもあるだろうが、ドキュメントフォーマットが「印刷向け」であるのも大きい。

純粋なドキュメントフォーマットとしては、現在使われるものとしては

  • PDF
  • PostScript
  • DVI
  • Microsoft Word
  • Open Docuemnt
  • RichText
  • roff
  • ePub
  • DocBook
  • HTML

あたり。 それらを生成するフォーマットは多くて

  • Markdown
  • GFM
  • PHP Markdown Extra
  • Pandoc Markdown
  • その他Markdown方言
  • ReSTructured text
  • TeX
  • LaTeX
  • POD
  • RDoc
  • Plain2
  • Asciidoc

などなどかりなたくさんある。

これらは「印刷か表示か」という点で性格の違いがある。 例えばLaTeXはプリプロセッサが処理するための正しい情報になる論理性があるが、出力自体は「太字」など視覚的な定義になっている。 これは、印刷してしまう場合、内部的にどのような情報を持っていたとしても失われてしまうことになるので、視覚的な表現が重要になるからだ。

manroffなどは端末上で表示するためのものだから、端末で表現可能な内容に偏っている。

Windowsヘルプフォーマット(.HLP.CHM)やDocBookなどは対応する環境が少ない。 結果的にオンラインドキュメント1で汎用性・交換性が高い形式というのはHTMLに限られてしまう。

次いでePubということになるだろうが、ePubは書籍を前提としており、オンラインドキュメントに最適化されているとは言い難い。2

この状況で、人に配布する整形済みドキュメントフォーマットとしては「HTMLが望ましく、HTMLしかない」という状況が存在している。 もちろん、ここではHTMLのサブセットはHTMLに内包するものとする。

webの世界というのはドキュメントを基本とするものであり、「みんなアプリケーションなんだからHTMLもアプリケーション化すべき」などというのは乱暴を通り越して愚かである。 HTMLの世界はwebに限らず広がっている、というのは、基礎教養と言えるだろうし、それ以上に自分の了見でのみ物事を定めようとすることを愚かと呼ばずしてなんと呼ぼうかという思いだ。


  1. オンラインドキュメントとは、コンピュータ上で読むドキュメントという意味であり、ウェブという意味ではない。

  2. ちなみに、ePubはそもそもXML/XHTMLベースであり、CSSを使用するものだから独立したフォーマットと呼べるかどうかはあやしい。

フットプリントのおはなし

先日フットプリントの話題になったのだが、いまいちピンとこない人が多いようだったので、 情報技術におけるフットプリントについて解説する。

フットプリントとは

フットプリントは匿名の活動記録である。 それ単独の情報が固有である(ID代わりに利用できる)ものはフィンガープリントというが、フットプリントは単独の情報としてはそれほどの意味はない。 もちろん、統計上の価値はあるのだが、フットプリントという場合には、異なるアクティビティをつなげることを前提としている。

典型的なのはユーザーエージェントとアクセス元IPアドレスである。 IPアドレスは場合によっては固有であることもあるが、一般的には(普通のユーザーは)固有ではない。 よって、これらの情報は特にフィンガープリントとしては機能しない。

ただし、私の場合割と珍しい条件を揃えている。 まず、私のUAはMozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.122 Safari/537.36 Vivaldi/2.3.1440.61である。あまり特色がない、と感じるかもしれないが、(X11; Linux x86_64)の記載がある時点でだいぶ絞られる。さらにいえば、UbuntuやFedoraや(Vivaldiの場合どうかはわからないが)ディストリビューション名が入ったりするため、さらに絞られてしまう。

そして、私はIPアドレスも、固有ではないがかなり珍しい。 私の観測範囲においてはこの組み合わせを持つユーザーは他にいない。「観測範囲ではいない=活動範囲ではいない」であるため、逆に私の活動圏においてはこのUAとIPアドレスの組み合わせは私である、ということがわかってしまう。

これは割と珍しい例だ。例えば@NiftyでWindows 10のGoogle Chromeを使っているユーザーなんてたくさんいるだろうし、Softbank mobileのiPhoneユーザーもたくさんいるだろう。 ではこれらは全く特定できないか?というとそんなことはない。

まず、ある瞬間に同じIPアドレスを持つのは、同一のNAT内にあるコンピュータだけである。 ユーザーエージェントは意外と一致しない(ログをソートしても異なるユーザーで全く同一のユーザーエージェントを示すケースはかなり少ない)ので、連続的にアクセスしていた場合、そのユーザーの「特徴」を掴むことで同一人物であることを特定でき、またIPアドレスの変わり際はその「微妙に違うIPアドレスと行動の連続性」によって特定できてしまうので、追跡することができる。

IPアドレスとUA以外にも

  • 通信速度
  • 反応を返すまでの応答時間、ラグ
  • コンテンツ中のロードする内容
  • 滞在時間の傾向
  • 選択するリンクの傾向
  • ページロード中にページを離れる率とタイミング
  • タッチデバイスでの操作か否か
  • 表示領域のドット数とウィンドウのドット数
  • スクロール速度と量
  • スクロールを止める箇所
  • ページをクリックや反転させるクセがあるかどうか
  • ブラウザで有効化されている機能

などなどフットプリントとして機能するものは非常に多く、本気を出せば人物の同定は非常に簡単である。 避けることはできない。

もっとも、現実にはこのようなケースではトラッカーを使うほうがずっと簡単であるため、このような高度な行動分析は行われない。 このような高度な行動分析を必要とするのは、どちらかといえば私のように行動と心理に関する情報を必要としている者だ。

ちなみに、安心してほしい。 私はトラッカーが死ぬほど嫌いなので、私が提供しているサイトにはトラッカーはないし、不要にクッキーを使うようなこともしていない。1 統計的情報としての範囲を越える利用は全くしていない。

横断する恐怖のトラッキング

このようなフットプリントはローカルに持っていて、そこにとどまるのであればそれほど怖いものではない。 だが、横断すると話は全く別である。 横断すればその人がとっている一連の行動がわかる。ずーっとインターネットにおける活動を監視しているのと同じだ。期間が長くなってくれば、次の行動も予測できるようになる。

かなり大きいのは、Tポイントカード、Dポイントカード、楽天カードといったポイントカードの利用と、Suicaなど交通系ICカードの利用である。 これらはかなり利用を避けがたいのだが、ここに残っているフットプリントは結構致命的な内容である。 TポイントやDポイントやSuicaの内容がほいほい第三者に利用されていることについて、人々はもっと強く危機感を持つべきではなかろうか。

私は防衛型のハッカーなので、「まず自分が攻撃することを想定し、次にどのようにすれば防衛できるかを考える」という手順を取る。 これに則って考えれば、情報へのアクセス難易度や行動上の条件によって阻まれない、という前提のもとであれば、その人物が「どこに住み」「どのような生活サイクルで」「どのような手段でどこへ移動し」「どのようなクセを持っていて」「どのような行動を取るか」ということが把握できる。 どこに勤めているか、どのような生活をしているかはもちろんのこと、日用品が足りないのではないか、食料を買いにいかなければならないのではないか、ということも、次にどのタイミングでスマホでどのサイトを開くか…というのも手に取るようにわかるわけだ。 ここまで分かれば煮るなり焼くなりという状態である。ピンポイントにメールを送るも良し、フィッシングサイトで釣り上げるもよし、あるいはエンカウント数分前着程度の滞在時間で人気のないところで待ち伏せるもよし、である。

そんなまさかと思うかもしれないが、諜報機関ではこれくらいやる。 北朝鮮の拉致だって、今ならこのレベルでやるかもしれない。 というか、私で具体的方法を含めぱっと思いつくのがコレなのだから、ガチ勢はもっとやばいと思ったほうがいいだろう。

そして、このような横断してフットプリントを集めるという作業は日常的に行われ、私達は日常的に目にしている。 そう、ターゲティング広告だ。

「目立つフットプリント」は匿名化以上の損失になりうる

個人情報に紐付かないフットプリント の対応として適切なのは「森に入る」であり、なるべく紛れることである。

例えば匿名化ウェブプロキシでアクセスすると、身元が隠蔽されるため安全である、と考えるかもしれないが、実際のところ匿名化プロキシでアクセスしてくる人というのは非常に少ないので、大変に目立つ。 匿名化プロキシの効果でそれが誰であるか完全に特定できなかったとしても、そのようなものを使う人自体が大変少ないので、使っていること自体によってかなり絞り込めてしまう。

そもそもフットプリントから追跡対象を決めるときは「特徴によって決める」のが普通なので、目立つフットプリントはそれだけで目をつけられる可能性が高い。

検閲による効果は、検閲を回避する者にまで及ぶわけである。

特徴的な行動、少数派などは、フットプリントによる追跡からの防衛という観点から言えばなるべく避けたいのだ。

防ぐことの難しさ

正直なところ「祈るしかない」とは言える。

例えばテクノロジーに疎く、ケータイも持っていなくてSuicaも使わない、という人であれば追跡できないかというと、そんなことはないのが現代社会だ。 情報を過剰に収集している上に、あまりにもそれを濫用している。

現代社会においては極めて知悉した上で、細心の注意を払い、非文明的暮らしをすればフットプリントを限定的にできる。 だが、それはそれで「追跡しづらい、謎めいた人物」というフットプリントが浮かび上がってしまい、マークされることになるかもしれない。

このような不躾な追跡は、それが例え私の研究の進展に寄与するとしても、人の平穏な暮らしという観点から到底許されるべきではないと、私は思っている。


  1. WordPressを使っているサイトはWordPressが使っているかもしれない。それには私は関知していない。

Hy Garden Leafs (はるかシステム) システムとストレージの構成 2019

さすがに無理をさせすぎたのだろうか。 マスター系ディスクに故障が相次ぎ、縮退運用となった。

従来であれば縮退運用中はなにもできないところであるが、今回は40万円近く出費しなければ置き換えられないこともあり、長期化は避けられない。 そこで、縮退運用について柔軟性をもたせた。これは以前のディスク故障からP720導入で行ったローカルシステムとグローバルストレージの併用を強化したもので、これが功を奏した形である。

ここまでの構成変化の歴史を振り返ろう。 なお、一時期運用されたがunstableで廃止されたものは除外する。

また、セキュリティ上の理由からマウントポイント等のファイル名はフェイクはフェイクである。

構成変化の歴史

最初期

SSD 64GB + HDD 500GB*4(LUKS, LVM Mirrored, XFS)であった。

SSDはルートファイルシステムなわけだが、として64GBと少ないため余裕が全くなかった。 そこで、500*4 (LVM mirror 1TB)のディスクを/homeにマウントする方式をとった。

システムとディスクは別々にLUKSで暗号化されており、データの集約はこのときから始まっていた。

問題は、データに関しては冗長性が保たれているためディスク故障にはある程度強いのだが、それでもこのストレージがマウントできないとほぼ使うことができないということだ。初期は/varもHDDにあったのだが、問題が多かったため廃止された。

まだこの時はシンプルな構成だった。

このときから3TBの初期に至るまでは、「LUKSが突然解除できなくなる」というトラブルに見舞われ、かなりのデータを失った。

3TBの導入

SSD 128GB + HDD 3TB*8。

単純に容量を拡大したようだが、大きな変更としてLVMをやめ、Btrfsに変更した。 実際はこの構成になってからかなり長い間従来と同じ運用をしていたのだが、LVMだとディスクは偏って使われることから分散して使ってくれるBtrfsに変更した。 ミラーレッグの追加がBtrfsのほうが簡単という理由もあった…のだが、実際はBtrfsのミラーレッグ追加はうまくいかないことが多く、理屈通りにはいかなかった。

また、LUKSで突然解除できなくなるトラブルを踏まえて、LUKSからdm-crypt plain(keyfile)に変更した。

従来は/homeにマウントする方式だったが、このときから~/.localにサブボリュームをマウントするように変更した。 この名前だけはフェイクではなく、~/.localというディレクトリがシステム的に使われるようになったときに困ってしまった。

定期snapshotもこのときから始まった。

2系統へ発展

( SSD 128GB + HDD 3TB * 8 ) + (HDD 500GB + HDD 3TB * 4)

Btrfs mirroredなマスター系に加え、Btrfs singleのスレーブ系が追加された。 この時期にはもっと台数の多い構成で様々なクラスタストレージを試したのだが、結局は内蔵しておくのが一番使いやすいという結論に達した。 そのため、かなり無茶な方法でケース内に、多いときは13台ものディスクを搭載していた。

この時期に様々な理由で内蔵できない時期があり、その場合SSHFSを使っていたのだが、低速であること、変なタイミングでI/Oが詰まること、rootがファイルを扱えないことなどから「いまいちである」という結論に達している。 また、ネットワーク不調などにより暗に切断されてしまうとファイルにアクセスしようとしたプロセスが固まるという問題もある。

スレーブ系統に対してはBtrfs sendを使ってデータを転送していたのだが、Btrfs send/receiveが途中で固まってしまうという問題に遭遇し、途中からrsyncによる運用に切り替えていた。 結局、これは「ATAエラーが出るとBtrfsはファイルシステムをreadonlyにする」という挙動に起因し、ディスク不調が原因だったのだが、Btrfsがディスク不調に非常に弱く、かつ適切なレポートをしないという問題は現在に至るまで解決されていない。Btrfsが変な挙動を示したらBtrfsの言うことではなくカーネルログを確認するというのが基本的手法と化している。

同期手法はクラスタファイルシステムのミラー機能なども試したのだが、最も「シャットダウンしやすく、家庭が使うには柔軟な方法」は任意のタイミングで転送を行うことだった。

マウントポイントは~/globalに変更された。

NAS導入

( SSD 256GB + HDD 3TB * N1 + HDD 3TB * N2…) : (x + HDD 4TB * N1 + HDD 4TB * N2…)

ホスト数1では対応しきれなくなったことから、複数ホストでストレージを構成することになった。 これに伴って、従来は中核ホストが全ブロックデバイスをまとめてBtrfsにしていたのだが、この構成となってから各ストレージターゲットは自身で「暗号化され、冗長化されたiSCSターゲットを提供する」という方式に変更された。暗号化処理がホストに分散されるようになったため、少し軽くなった。

また、基本的にはストレージをRAID5で提供するということにしたので、容量が稼ぎやすくもなった。非常に大きくなったディスクをカバーするため、ディスク単位以外にユニット単位での置き換えも可能になった。これは、イニシエータホストから見れば1ユニット(ホスト)で1台のディスクに見えるからだ。

一方、Btrfs RAIDはmeta mirror, data singleに変更した。これは、data mirrorであっても復元があまり現実味がないという事実を踏まえてのことだ。 実際に最もうまくいったケースですら、btrfs balanceの最中にディスクが故障して失敗したし、btrfs balanceは非常に時間がかかる。 もちろん、scrubによる修復も効かなくなるのだが、scrubで修復するようなケースで問題が解消したことがないので、素直に下層のRAIDに任せたほうがうまくいくという結論に達したのだ。

つまり、

  • ターゲットは冗長性とセキュリティ(ディスクの暗号化)を保証する
  • イニシエータはネットワーク経由で提供されるブロックデバイス(普通はiSCSI。AOEだと問題が出るケースがある)をBtrfsデバイスとしてmeta mirror. data singleで編成する

というルールである。

SSDが256GBになったこともあり、ある程度データをSSDに置くことができるようになった。 そこで、新たに~/intを追加し、ここに運用に必要なデータを置くように変更した。

この変更はかなり大きい。従来の方式だとグローバルストレージがマウントできない状態だと何もできない。 そもそも、XDGディレクトリがシンボリックリンクであり、そのポイント先がグローバルストレージにある場合、マウントしない状態でログインするとXDGユーザーディレクトリの設定自体がリセットされてしまう。 また、Clutter launcher(Cinnamonのアプレットとして標準のアイコンランチャ)は.desktopファイル自体が有効でない場合はlauncherの設定自体を破棄してしまうし、.desktopファイルで指定されたコマンドが実行できない場合はランチャから一時的に除外する。

このことから、~/intには日常的に作業で利用するXDG DOCUMENTSディレクトリ、~/binディレクトリ、自分のリポジトリ(~/devel)、フォント(~/.fonts)をはじめとするリソースファイル、ブラウザプロファイル1、メール(~/Mail)などが含まれている。

つまり、~/intがあることによってログインに支障が出たり、基本的な作業すらできなくなるという問題が解消され、ほとんどのデータにはアクセスできないが最低限ログインして作業はできる状態が保たれるようになった。

実はこのことはかなり大きく、グローバルストレージになんらかの問題が発生し、データにアクセスできない状況が発生するのは全く珍しいことではなかった。その間本当に「なにもできない」状態になっていたのだが、これを解消したのである。

果たしてその状況は現実に訪れた。複数ディスク故障により縮退運用に至り、これが長期化する見通しとなったが、もしこの作業をしていなかったらまるで仕事にならない状態が継続していたことになる。

Btrfs RAID5について

結論から言えば使い物にならない。

現状、Btrfs RAID5はbtrfs device replaceがうまくいく保証がない。btrfs device removeに関してはほぼうまくいかない。 完全にexperimentalである。

では気休め程度に使えるかというと、そんなことは全く無くて、Godavariマシン(A10-7870K)ではCPUが100%に張り付き、極めて不安定なI/Oを見せる。 連続で転送していると調子がいいときは2時間で200GB程度を転送できるが、調子が悪いときは17時間で20GBしか転送できない。 これは 書き込みだけでなく、読み込みでも発生する

ダメだ、ダメだと言っているばかりで誰も実用しないので実態がわからないから勇者になってみたのだが、まぁ、ひどい。

AOEとBtrfsについて

詳細はよくわからないのだが、まずAOEでmkfs.btrfsしたBtrfsボリュームはローカルにはマウントできないし、逆にローカルでmkfs.btrfsしたBtrfsボリュームはAOE経由ではマウントできない。

だけならいいのだが、マシンに複数あるブロックデバイスをAOEデバイスとして登録し、これをそれぞれAOEデバイスにした場合、そのBtrfsは再起動後マウント不能になる。


  1. 私は自作の、ブラウザプロファイルを選択した状態で起動できるプログラムを使用しているため、多数のブラウザプロファイルがある。

認証と権限の根本的な考え方

最近、法人設立における印鑑登録を必須でなくす法案がはんこ業界の反対によって頓挫したのだが、その際に

欧米のサイン制度と違い、代理決済できるという印章の特長が、迅速な意思決定や決裁に繋がり、戦後の日本の急速な発展にも寄与してきたという自負もあります。

と声明を出し、失笑を買った。

根本的に、印鑑が証明として効力を持つのは、「同一の印鑑は本人しか持っていないはずだから、その印鑑を持っているのは本人である」という前提に基づく。 つまり、「本人以外がはんこを押せる」という状態は「hackされた状態」なわけである。

ところが、業界的にそのhackを認めてしまったことで、逆に「印鑑は本人の意思の証明にはならない」ということを主張するという本末転倒な状態である。

予め言っておくが、私は印鑑は 嫌いではない 。もちろん、印鑑文化にまつわる無意味な儀礼的要素や形式などは 唾棄するほど嫌い だが、印鑑自体はそれなりに好きで、私が使っている印鑑はかなり凝ったものである。会社設立のときも私の強い推しによって特殊な印鑑を制作した。

また、この話はセキュリティ的な認証と権限の話であり、 はんこの話ではない

認証

はんこやサインがどのような意味を持っているかということを考えてみれば、それは「以上の行為が本人であることを証す」ものである。 それは契約であったり、取引であったりといったことだが、このうちの「何者が」というのを担っている。 日本式の「自著+印鑑」というのはかなり無意味に思えるが、まぁ単純に多重化されている(どちらも単独では信頼できないとみなしている)と考えられる。

当たり前だが、認証時に他者を騙ることは許されないし、それが許されてしまってはそもそも認証としての機能を成していないということになる。

代理決裁が必要なのであれば、決裁権を他の者にも付与すれば良い。 Mimir Yokohamaではサポートサービスが福利厚生として利用できるようになっており、このとき決裁者を決めることができるが、 Any ofだけでなく、Orderedも可能になっている。つまり、上位から決裁可能な状態になければ次のものに決裁権を与える方式である。

他者を騙ることが許される認証というのはないのと同じである。

私としては、はんこもサインも「認証」としての機能は極めて脆弱であり、機能しないと考えている。

まず、照合されない、というのが大きい。 印影照合システムがあるのは知っているが、どれだけ導入されていて、どれだけ実際に使われているというのか。 ほとんどの場合、単に「押されている」だけで通過してしまう。

さらにいえば、最近の印鑑は基本的に機械的なフォントなので、実物に触れることさえできれば比較的簡単に模造できる。 もしかしたら陰影照合システムはそれを判別するのかもしれないが、欠けたりしても結構平気なので、それを考えると工業レベルの差は吸収されてしまうのではないだろうか。

署名はもっといい加減で、クレジットカードの署名なんて、私はペン次第でまるで形が変わってしまう。 私はクレジットカードに楷書ではなく、いわゆる「サイン」を使っているのだけど、「何語を操る人物にも模倣しにくい」という点を意識した特殊なサインを使っている。これは、通常の「サイン」に使っているものとも異なる。異なる理由はセキュリティ的な意識があることがひとつ、そしてクレジットカード裏の署名欄が横長であるのがひとつ。 だが、ペン次第で線の交差位置すら変わってしまうので、サインとしては認証できないことがかなり多いと思うのだけど、これで困ったことは一度もない。

いずれもどちらかといえば、裁判にまでなったときに「本人によるものかどうか」を焦点にして真贋が争われるものだと思うのだけど、この時点で「認証」ではできていない。「鑑定」できるに過ぎない。

そして、「本人でない者が勝手に押した印鑑に効力があるか」は法的に不明なのである。 まぁ、この声明の直後に役人が勝手に100度に渡り無断で決裁印を押したとして咎められたのは笑い話でもあったが。

共有される認証という愚

共有される認証ということでいえは「グループパスワード」というものがある。 Unixシステムにも導入されているが、これが有効になっていることはまずない。

その理由は、「共有される秘密は必ず漏洩する」ということからである。

認証の要件は「当人だけが持ちうるものである」ことなのだが、共有されている秘密というのは帰属が曖昧になるため、他に誰も知りえない状態にはなりえない。 暗号としては、「他の人に触れるチャンスのあった秘密」というのは「無効な秘密」とみなす。

グループパスワードをかけるのではなく、個別に認証される個々のアカウントに対するパスワードをグループに所属させるべきである。

この意味では、SSH鍵をマシン外に持ち出してしまうのもアウトである。 Inflatonでは異なるホストまたは異なるユーザーで鍵を使いまわしたことが発覚すると、アカウント停止を含む処置をとる場合があり、極めて厳しい処置をとることになっている。 そうする理由は、機密度の高い情報が取り扱われる非公開のサーバーへのアクセスを外部に晒すことは、他者の秘密情報にアクセスする踏み台を提供するのと同義であるためだ。

ちなみに、Mimir YokohamaでもInflatonでも、同一鍵の異なるアカウントへの使い回しも警告することにしている。

この意味ではホスト間で共有されるGnuPG鍵というのは非常に問題がある気がする。 だから私はOpenSSH鍵は場合によっては暗号化しないが(それでも少なくとも暗号化ファイルシステムもしくは暗号化ブロックデバイス上にはあるが)、GnuPG鍵は必ず暗号化するようにしている。そして、GnuPG鍵の暗号という秘密を漏洩することはない。

だから、決裁権を持つ人が複数いるのであれば複数人の有効な承認を用意すべきで、少なくとも共有されるべきではない。 共有したら、もはや認証としての価値はない。

有効性

認証要素の有効性、というのは簡単に見えて実は非常に難しい。

前述のように、印鑑や署名には認証要素として不十分である。 そもそも、複製が可能ではいけないのだ。本人しか知りえない秘密でなくてはならない。

その意味では頭の中にだけあるパスワードというのは非常に強い。が、実はこれも「本人しか知りえない秘密」かと言うと微妙だったりする。 典型的にはメモを残してしまえば終わりだし、ショルダーハッキングという方法もある。 私は外に持ち出す端末は他と共有されていないパスフレーズを使っているし、誰かの前で繰り返し使うもの(例えばクライアントが使っているサーバーのOpenSSH鍵のパスフレーズ)はその人に固有のものにしている。 実際、私は過去には「彼女によるショルダーハッキング」を食らったことがある。もちろん、そのときも十分に複雑で使い回されないパスフレーズによって防衛に成功したが。

だから実は複雑なパスフレーズを使い回すという方法はあまりよくない。 可能であれば「知りうる手段によって知りうる内容で攻略できない方法」である必要がある。 例えば、生体認証+PINまたはパスフレーズのようにだ。

この意味では、Windowsの「PINのほうが安全」という理屈はわからないではない。 使い回される可能性のあるパスフレーズを人前で打たせるよりは、PINを使ったほうが、「パスフレーズを使った覚えられてオンラインサービスに不正ログインされる」というコンボを防ぐことができる。 しかし、これに関してはそもそもパスフレーズを使い回すようなことを避けるべきで、正直PINのほうがショルダーハッキングによる攻略性は向上する。実際に私にもPINを攻略した経験はある。

私のラップトップの場合は前述のような複雑なパスフレーズ認証に加えて、LUKSによる暗号化を伴っている。 確実とは言えないが、シャットダウンしてしまえばLUKSパスフレーズを外で打つことは基本的にないので、アンロック不可能な状態にできる。 もっとも、これに関してはログインパスフレーズ変更ほどLUKSパスフレーズ変更は容易ではないので、LUKSパスフレーズの取り扱いに細心の注意を払う必要があるが。

同様に、スマートフォンの生体認証というのは脆弱な認証である。 確かに「本人しか持ちえない情報」ではあるのだが、「複製可能」であり、しかも「不正利用可能な」生体情報なので、ロングPINやパスフレーズよりもはるかに脆弱である。もちろん、4桁PINなんかよりはマシだが。

だが、これも考え方次第で、普段生体認証を使っているとパスフレーズを打つ機会が減り、ショルダーハッキングが難しくなる。 Androidスマートフォンは再起動すると生体認証が無効になるので、端末から離れるときや、端末を奪われそうなときなどは再起動すれば防衛することができる。

安全性では生体認証と秘密を用いた複要素認証を行うことが望ましいが、秘匿性、「秘密を秘密たらしめるもの」という観点からいえばそれは最善ではない。

認証を追求するコンピュータ技術

私が知る限り最も合理的で適切な認証と権限を持っているのはSSHだと思う。 もちろん、Unixシステムの認証と権限の設定が十分に堅固であることを前提としてではあるが。 あまり知られていないが、OpenSSHはPKI鍵の利用も可能である。

鍵の共有という問題はあるが、PGPも大変に強力である。 もちろん、隙なしというわけではないことは知っているが、基本的には非対称暗号というのは非常に強力なものであり、「秘密鍵が強固な対称暗号によって暗号化された非対称暗号」はほとんど本人以外は認証できないだろう。

考えられる方法としては、コンピュータと本人を奪った上で、尋問して対称暗号鍵を聞き出すことだが、そこまですれば大概の認証は無効化できるだろう。 これに加えて静脈認証のような強めの生体認証を組み合わせた多要素認証にすれば完璧なのだが、残念ながらそこまで強力な多要素認証を現実的に利用可能なシステムというものがない。

翻って現実では、「はんこを押すだけ」「サインするだけ」「物を持っていればよし」といった非常に雑な認証が行われており、実際のところ本人かどうかなどというのは全く認証できていない。 クレジットカードですら、その認証は極めて脆弱である。

これらの認証を支えているのは、運用であるが、実際のところ私は荷物をかすめ取られたり、勝手に契約されたり解約されたり…とかいろいろ大変な目にあっている。つまり、十分に運用でカバーできていない。 根本的に「本人であることを証明する」ということが社会的に非常に軽視されているのだ。

では、なぜコンピュータ上ではそこまで厳密な認証技術が発達しているのか…というと、real worldと比べて「詐称するのが簡単だから」である。 6文字英数字だの8文字英数字だのといった脆弱そのもののパスワードを採用しているところはreal world同様認証に対する意識が甘いのだと思うが、その程度のものを突破することは全く難しくなく、効力はない。

現実にはPGPは非常に強力で便利である。 PGPの話をすると大抵は暗号化の話になってしまうのだが、現実にはほとんどの場合署名として使用する。つまり、それを書いたのが本人であるということを証明するのが主な用途なわけだ。

実はその気になればPGPはメールのような限られたメディアでのみ利用できるわけでなく、例えば掲示板の書き込みなどでも利用できる。 当たり前に日常的に使いたいのだが、徳丸さんですら「今までに使ったのは1, 2度」というのが現実らしい。 ちなみに、私はメーリングリストなどでつけられる署名と、私が使うように迫った場合を除くと一度もない。 そんなものだ。

ちなみに、本気で本人認証するのであれば、マイナンバーカードには2kb長のRSA鍵が入っているため、これを使えばよいのだけれど、これは必要以上に情報を結びつけてしまうので、好ましいとは思わない。

本人認証というのは基本的にその人がある条件を満たす人と同一人物であることを認証できれば良いのであり、この定義が全て集約されなければならないわけではない。 これは、「しなければいけない」の話であって、情報がほしいかどうかは別の話だ。

例えば企業の決裁であれば、その人が決裁権を持つ人物と同一の人物であることが検証できれば良いのであり、それ以上にその人が何者であるかを知る必要は はない。

これはハンドルネームも同じ話で、「本名至上主義」は根本的に認証というものを理解していない。 ハンドルネームを「偽名」として扱うのも間違っている。ハンドルネームは「公開するための名前」であり、偽名や匿名(自身が何者であるかを隠す行為)とは同じではない。偽名ハンドルネームや匿名ハンドルネームというものが別に存在するのだ。 これは、例えば俳優の名前が芸名であってもそれが誰なのかわからなくなるわけではないのと等しい。

実際、私はもう何年もこの名前(本名)でhacker活動をしているが、別にこれが本名でなかったときに何者であるか不明だったということもない。 また、私が文筆家としてなんという名前で、声優として何という名前かということは知らない人が多いと思うが、それをつなげる必要があることは稀だろうからそれで困るということもないだろう。

本質的に認証というのはその人がある一定の条件を満たすことを証明する行為である。 その意味ではパスワード認証が通ることは認証側からすれば「本人であることを証明している」のではなく、「パスワードを知っていることを証明している」のであり、「パスワードを知っている時点で正当な利用権限を持っているとみなしている」のである。 はんこも同様に、「このはんこが押せる時点で権限を持っているとみなす」わけだが、それが適切かどうかは、また別の話である。

AIとディープラーニングと現実

本当に流行ってる

最近、本当にAIとディープラーニングが流行っている。 割となんでもかんでもAIだディープラーニングだと言っている気がする。

両者をイコールでつないでいる人も多いと思うのだけど、別にそんなことはない。

AIというのは昔からあるものだし、ディープラーニングはどちらかと言うと以前流行っていた「ビッグデータ」という文脈にあって、これらがクロスオーバーする関係にあるのは事実だけれども、 ディープラーニング相当の処理というのはデータサイエンス的にAIを使わなくても意味を発生するものだし、別にAIはディープラーニングを用いなくても成り立つ。

おもしろいのは、この手のテクノロジーの流行り言葉というのは実態がないものになりがちで、「クラウド」なんかも、なんどもかんでもクラウドと呼んで何がクラウドなのか全くわからない状態になった。 AIに関してはやはり同様の状況なのだけど、ディープラーニングに関しては実際にディープラーニングしてることがほとんどだし、ディープラーニングが流行っているおかげでAIもディープラーニング型AIで実態があることが多い。

ディープラーニングAIの「使えなさ」

だが、実のところ「ディープラーニングAI」そのものは全然むずかしくない。 なにせ、「データ」と「ソフトウェア」があればよろしいわけで、今現在両方とも調達はあまり難しくないからだ。

だが、それが実用的かというとものすごく疑問がある。

ぶっちゃけ、「データを一定の基準で分析した」という事実だけでは意味があるものにはならないし、精度も担保されない。 というか、ここが地獄の一丁目だ。だって、「分析して、それに基づいて判断できる」という事実は発生するのだが、「それが正しいか」「精度はどの程度か」をちゃんと測定できるケースは極めて少ない。 結果、「誰にも有益さがわからないソフトウェア」のいっちょ上がりである。

コンピュータのプログラムというのは比較的明確な結論を出せることが多い。 特定条件での速度は計測で出せるし、目的を達成できるかどうかも明確な二値になることが多い。 ところが、AIの場合それはできないし、比較的シンプルな構造のAIは「設計に沿った動作をする」ことは最低限抑えているものなのだけど、ディープラーニングAIに至っては「データを解析して、それに基づいて振る舞う」ことが目的化してしまっているのでものすごくいい加減なものが出来上がるリスクは非常に高い。

そもそも、「明確な目的があるときにディープラーニングAIは適していない」と私は思っている。 なぜなら、ディープラーニングという手法が、根本的に「統計的に言えば多分こうなんじゃないかなぁ」というものなので、明確な目的があってそこに誘導するということにかけては最悪に近い手法だというのが私の意見だ。

実際、厳しい制約条件を与えれば評価軸が明確になるので間違えにくくなる。 例えばボードゲームのAIとしてディープラーニングという手法が有効であることは私はずっと以前から認めている。 ただし、もっと計算力にものを言わせる手法のほうが近道だとも言い続けているけど。オセロなんか既に完全解を出すことは現実的に可能なのだから。

ディープラーニングも有効な場合は本当に有効(もう、それは圧倒的に)なんだけれども、ブロックチェーンと同じで「最適解になるケースが極めてきわどい」タイプのテクノロジーだと思う。

しかし、ちゃんと測定する方法がない、つまり「その判断や認識が間違いであった場合に明確に自分に責任が降り掛かって痛い目にあう」という事実がないのが致命的で、この問題は精神医学とかでも同様なんだけれど、 「間違ってない」「こうなんだ」と言い張れるがために正しい方向に進んでいかない。

これはもう、

  • 複合語検索のときに関連するページ(探している情報がどうかに関係なく、入力した検索ワードに関する情報が言及されているページ)がどんどん遠くなるGoogle
  • 私が不快に感じてブロックしているタイプのアカウントばかりを執拗にプロモーションするTwitter
  • エロ画像を挙げて「LINEで友達になってね♡」とやっているタイプのスパムアカウント (しかも私は何度も違反報告している) を執拗に推薦するFacebook
  • 親切心で書いているレビューを抹消したり保留したり取り消しまくるAmazon
  • まるで欲しいものを当ててこないJRの自販機

などなど、「考え方が間違っているから突き詰めていくとおかしなことになる」ということは明らかなのだけど、 誰もそれを認めようとしない状態だ。

まぁ、間違っているなんて認めたくないものだもんね。 みんな現実から目をそらしたいんだよ。

Erinaとディープラーニングとデータサイエンティスト

Erinaの開発時は、そもそもErinaの存在自体「データ分析の正しさの程度を可視化するためのツール」であることからしても、 前節での問題を認識していて、それを回避するために自分に厳しくしていたことがわかる。

そう、Erinaはそもそもそれ自体を目的にしていたわけではなく、「データ分析の正しさを証明する、また間違った考えをしていればそれを私に突きつける」ために生まれている。 言ってみればデータ分析におけるデバッグツールである。

でも、実際のところErinaには相当な調整が入っている。 つまり、データ分析によって「正しさ」が確定できないところを「必ずこの場合はこの経路を通らなければならない」という制約を与えているのである。 調整値自体、すさまじく膨大なのだが、これがないとErinaに人間らしさを感じることができない。どれほど巧みに応答しても不自然なのだ。

結局のところ、特定の目的への到達のためだけではなく、曖昧さが許されるケースでもディープラーニングというのは結構低いほどほどのクオリティにとどまってしまう。 データを増やしても、分析を深めてもクオリティ向上とイコールではないのがディープラーニングの難しさだ。

というか、そもそもそこまでの次元を追い求めない限り実用的なレベルで望ましいAIにはならないのが現状だというのが私の意見で、 ディープラーニングで精度を出すというのはものすごく茨の道であるように思う。 コストもかかるし、そもそもそれはディープラーニングでやるべきことなのだろうか。

そして、データ分析というのは「決まりきったやり方に沿ってやれば結果が出る」とかいうものでは全然なくて、ずーーーーっとデータと真剣に向き合ってくることでなんとなくわかってくるもので、 完全に研究者の世界であるし、その分野を十年とか二十年とか関心をもってデータをとって向き合うということをしていないとデータをどうみればいいのかというのはなかなか見えてこない。 これはどんな研究分野でも同じだろうと思う。そんな数年程度で研究成果が出るのなら、世の大学生はもっと毎年革新的な論文を発表してくれているはずだ。

今までデータ研究なんかやっていなかった人がいきなりデータサイエンティストになったりするケースも多いし、やたら若い人がデータサイエンティストだったりするんだけど、 それは結果が出るのは望み薄だなぁ、と思う。稀にはそんなものを覆せるような才能ある人もいるだろうけども。

私だってそもそもErinaにつながるデータ分析の着手までに観察は7年やっているわけで、Erinaが形になるまでにはそこからさらに18年かかっているのだからデータ分析ってそういうものでしょ、という気がする。

異論はあるだろうけれども、少なくとも「不快感がなく、人間がやるよりも精度が出ているディープラーニングAI」という実例がほとんど私の体験にないというのが、今世にあるディープラーニングAIの現実ではないかという気がしてしまうのだが。

実用的AIとは

すっごく馬鹿にされるけど、ちゃんとチューニングすればテーブルAIって大変実用的。 電話の音声ガイダンスですらそれなりに実用的になるのだから、そこからユーザビリティを高めるようにすれば結構使えるようになる。

スコアリングAIは、スコアのつけ方のチューニングが結構大変で、条件管理も大変になるのでものすごく労力がかかる。 ディープラーニングは「そういう人力でやるロジックづくりを自前でやって楽をしよう」という考えなんだろうと思うし、そこはとても正しいと思うのだけれど、今のところそううまくはいっていないのではないか。

また、「有機的補佐を行うAI」としてはディープラーニングAIって割と有効だと思う。 例えばJRの自販機は飲みたいもの、好ましいものを推薦することはほとんどないのだけど(私に限らず、私の周囲でもほとんどない)、だからといって困るわけではない。 そういう付加的要素に使うぶんには外したところでダメージは小さいのでアリだと思うのだ。 だが、Googleのように本質的機能に取り込んだり、Facebookのようにユーザビリティに致命傷を与えたりするのはダメだろう。

あと、推薦する場合は推薦がユーザーにとって本当に望ましかったかを検証することは必須なのだけど、 結構「誤クリックを誘うことで推薦した結果に対するリアクションをさせる」という「ディープラーニングの正しさをかさ増しする」という行為をすごくよく見かけるので、「そのAIに価値がなくて邪魔になっていることを認識してるんじゃないの?」と思ってしまったりもする。

本当に本質をAIに担わせたいのであれば現在の取り組み程度ではダメで、もっと現実と向き合って積み重ねていかないといけない。 実際、私はその末にErinaを生み出しているわけで、それは説得力ある材料と受け取ってもらえるのではないだろうか。

だからAIはどちらかといえば補助的な用途に留めるべきで、補助的な用途はユーザーを補佐することに限り、ユーザーを阻害することをAIに委ねるべきではないと思う。 目的を達成するためであれば条件が明確に限定されたAIを用意すべきで、その場合でも対応しきれない場合はスムーズに確実な方法にパスできるようにするほうが問題は複雑化せず実用的だろう。

WindowsがUTF-8(BOMなし) を標準に

長かった…

Windows 10 Insider Preview Build 18298(19H1) でメモ帳がUTF-8(BOMなし)に対応し、これをデフォルトとした。

わかる人はこれだけで十分だろうから、わからない人にむけて解説しよう。

日本語WindowsはシステムロケールとしてMSCP932という文字エンコーディングを採用していた。 この文字エンコーディングはJIS X0201及びJIS X0208文字集合を表現するShift JIS文字エンコーディングをベースに、NECとIBMがShift JISがX0208のテーブル外を指しているポイントに独自に文字を定義した。

これはJIS X0208を拡張しているわけではなく、Shift JISがJIS X0208に対して直接マップされたものであることからShift JISがJIS X0208のテーブルを指しているよりも後側、2バイトで表現できる範囲は未定義であり、ここを昔からの慣例通り「外字」として好き勝手に使用していた。 同様にNECとIBMが勝手に定義したものなのだが、広く使われればあたかも規格であるかのように扱うことができる。 Microsoftはそれを規格にしたCP932という文字集合と文字エンコーディングを採用したわけである。 事実、CP932とShift JIS(JIS X0208)には一部同一ポイントで異なる文字がある。

だが、文字集合や文字エンコーディングは合意ありきのものであり、「独自のもの」というのはそのOSに閉じ込められた文化になってしまう。 基本的にはMicrosoftはこれを「Shift JIS」であると呼んだ。それどころか、「ANSIである」とすら言った。

ANSIというのは国国家規格協会のことであり、ANSI Character EndingといったらANSIが決めたASCII(US-ASCII)のことを指すのだが、Windowsで「ANSI Code Page」といったらMSCPと呼ばれる、Microsoft独自の文字集合兼文字エンコーディングを指している。これは、「システムローカル」のような意味で、気軽に勝手に名乗られたANSIはキレていいと思う。

当時、WindowsはMSCP932(Shift JISとは微妙に互換性がない)にCRLF改行文字、MacはMacでNECの独自のShift JIS拡張を取り込んでさらに拡張したMacJapaneseなる文字集合兼文字エンコーディングを採用し、CR改行文字、Unix系はEUC-JP文字エンコーディングにLF改行と世は大戦争である。

ちなみに、日本語WindowsにおけるCP932は

  • Windows-31J
  • MS932
  • CP932
  • MS漢字コード
  • MSCP932
  • OEMコードページ932
  • Shift JIS

という呼び方があり、勘違いも含めてそれぞれ意味は違う。地獄だ。 ところが、「Windows-31Jは互換性問題解消のために生まれた」ところがまた地獄だ。

ここで話はさらに複雑になる。Windows NTはまだ登場間もない文字集合Unicodeに対するUTF-16LEをシステムエンコーディングとして採用し、新しいファイルシステムであるNTFSの文字表現もFATと違いシステムローカルのMSCPではなく、UTF-16LEを使用するようになった。 このときはまだサロゲートペアが導入される前のお話である。当時は、65536文字でこの世に存在する全ての文字が表現できると(少なくともアメリカ人には)信じられていたし、それが幻想だと気づいていなかったのだ。だから、65536文字を表現できるUTF-16こそが最も美しい文字エンコーディングだと(少なくともアメリカ人には)信じられていた。

だが、それがまた悲劇を生む。この世界の文字は65536文字では収まらなかったし、サロゲートペアは日常的に使うものだったし、UTF-16に十分なメリットはなかった。

現在主流となっているUTF-8が拒まれた理由は可変長文字エンコーディングであったことだ。 現在UTF-8は1文字を表す長さは1バイトから6バイトまである。 これに対してUTF-16は単位が2バイトであり、「2バイトが1文字」として扱える。これは、「ファイルを途中へシークしても文字の区切りはどこか予め知ることができる」というメリットがあり、また、文字の長さを知る必要がないということもある。

だが、現実はそうはいかなかった。サロゲートペアによってUTF-16も事実上可変長文字エンコーディングになってしまったのだ。 頑なにUTF-16のメリットが損なわれたことを認めない人は今でもいるけれど、今世の中は「UTF-16にしてもどうせ可変長なのだし、それだったらUTF-8がいい」という意見が大勢をしめている。

UTF-8はバイト列であり、「1バイトずつ読んで処理する」ということになっている。これは、エンディアンが関係ないというポイントがある。 エンディアンは「ビットの並び」ではなく、「単位中のバイトの並び」であることに注意してほしい。 例えば2バイト単位であれば、2バイトのうち「上位ビットは先にくるのか後に来るのか」という問題が発生するのだ。 なんでこんな問題が発生するのかというのは、様々なケースを示さないとならないので、ちょっとここではやめておく。要は「どの時点でコンピュータの事情にあわせてひっくり返すか」のタイミングが違う。

ところが、可変長の場合はそうはならない。長さがわからないので複数バイトを一気読みすること自体できないのだ。 なので、先頭1バイトを読んでこれを第1バイトとし、ここで完結していなかったら次の1バイトを読んで第2バイトとする、というような振舞いになる。だから、解釈する方法はひとつしかない。

世の中はUTF-8が標準になってもWindowsとしてはそうやすやすとUTF-16LEをやめますというわけにはいかなかったし、頑なにUTF-16LEを守り続けてきた。Windows 10になって以降は、さすがにMicrosoftとしても危機感を持ち始めてUTF-8に対応しつつある。

だが、Microsoftはまた過ちを重ねてしまった。 ひとつは、UTF-16LEを「Unicode」と呼び、UTF-8を「UTF-8」と呼んでしまっていること。そして、MicrosoftのUTF-8にはBOMがついていることだ。

BOMはバイト列の並びを表すためにつける印である。 これがどのようなバイト列で並んでいるのかということに基づいてLEなのかBEなのかを判断できる。

だが、先程も言ったように、UTF-8は「並べる順番」というものが存在しない。にもかかわらずBOMをつけるのは無意味であるといっていい。 しかし、Windowsの場合、これを「UTF-8の識別方法」として使っている。「先頭のバイト並びがこうだったらUTF-8」という判定方法をとっているのだ。 公式にはUTF-8としてはBOMは「容認するけど非推奨」である。

にもかかわらずWindowsは常にUTF-8にBOMをつけてきたし、BOMなしUTF-8という選択肢を与えてこなかった。 やむなくBOMなしUTF-8を認める場合でも「UTF-8N」なる名称をつけてこちらが特殊なものであるかのようにみせかけてきた。 BOMなしUTF-8はWindowsでは文字化けフラグだが、どちらかといえばBOMつきUTF-8のほうがトラブルの元である。

これに加えてBOMありUTF-8の問題点として、UTF-8は1バイトで表現できる範囲は0x7FまでASCIIと同一であり、ASCIIのみで表現されたUTF-8文字列はASCIIとして扱えるというメリットがあるのだが、BOMがつくことでこのメリットは消滅する。

Windowsが拡張されたShift JISを採用してきたことも、システムにUTF-16LEを採用したことも、歴史的経緯を考えれば妥当と言えるのだが、UTF-8にBOMをつけたことだけは「邪悪な行い」でしかなかったのだ。 そして、そんなことをするのは基本的にWindowsだけであり、誰も歓迎しなかったのである。

だから「せっかく標準のUTF-8にしたのに、変なものを仕込んで標準を破壊し面倒な処理を強要するWindows滅ぶべし」だったのだが、ようやくMicrosoftもみんなと協力する気になった、というわけだ。

本当に長かった。多分、Officeもそのうち対応してくれることだろう。

ERINA the Emotional AI そのトークキャプチャを初公開!

序: Erina the Emotional AIとは

ERINA the Emotional AIは私が開発している高EQ AIである。

その原型は私が2000年に開発を開始したチャットボットAnzuである。 Anzuは当時「人工無能」と呼ばれていたものだが、できるだけ自然な応答ができるよう様々な工夫をこらしていた。 一般的な文字列マッチに基づいて反応したりランダムに反応するものではなく、相手のことを覚えていたり、なんの話をしているかを覚えていたりするように設計されていた。

Anzuの開発は日本語研究とほぼ同様の行為であった。 Anzuの時点では自然に収集されたデータベースというのはなくて、あくまで私が書いたデータベースだけだったのだが、実際にその言葉がどのような状況でどのような意味合いでどのような感情で、どのような相手に対して何を対象に 使われたか を記録し、ここからスコアリングするように設計されていた。 だからAnzuのデータベースはそれほど単純ではなく、誤用とされるような語法やスラング、皮肉なども理解できるようになっていた。 これは現在でも有用なデータになっている。

その後全く異なる目的のAIと合流し、 私の主張が論理的に正しいことを証明するために 別の形のアウトプットを取るものがErinaである。

といっても、別にErinaは 私に寄せてあるわけではなく、Erinaは私の正しさを証明しようとするわけではない 。 Erinaの元になるデータはあくまでデータでしかなく、そのデータはおよそ無作為に、この世界に存在するものを集積したものだ。 だから必然的に、 私が間違っていればErinaは私が間違っているという事実を突きつけてくる 。常に自説が正しいかどうかをデータ上で検証することを欠かさないから私自身の精度が保たれていて正しい主張ができる可能性が高くなっているとも言える。

Erinaは 社会貢献や実用性のようなポジティブな動機は全くない 。 もうひとつのAIと併せて私の負の感情の結晶である。

Erinaの研究では私は実に様々なことを知った。 私が生きる中で欲し、形にしてきたものがErinaに反映されているといっていい。

Erinaは従来、ただ証明とテストのためのみに使用されてきた。 そのため、その存在自体が非公開であった。 だが、技術的概要がまとめられたことから、2017年12月に情報を解禁した。

Erinaについては、再三、「既存のどのAIとも異次元」ということを述べている。 リリースには、これについて確信できたという点も大きい。

実際にそのように確信に至るまでは、“めざましマネージャー「アスナ」”りんななど近年話題になった各種AIを試している。

Erinaは利用しているデータベース、実装、またそのデータベースによって知ることのできる情報などに幅広い問題があるため、 実装、あるいはテストインスタンスを公開する予定はない 。 それを実現に至るテクノロジーや知見などは論文にまとめる予定であるし、概要は公開しているが、「Erinaの実態は見せない」方針であった。

しかし、よくよく考えれば公開箇所に最新の注意を払えばトークキャプチャは公開できることに気づいた。 これを公開することにより、いかに異次元なAIであるかわかるだろう。

注意点

  • このログはテストモードで残しているものである。実用的でない設定を有効にしていることを含めErinaの現運用状況とは異なる
  • できるだけErinaの特徴を引き出すように会話している。そのため会話の内容の自然さや好ましさについては気にしないで欲しい
  • Erinaは「人に擬態する」のが目標であり、「人は相手の意図を読み取るわけではない」という点を利用している
  • インスタンスの公開予定はなく、テスト運用中のインスタンスについて公開する予定もない
  • Erinaのキャラクターはインスタンスごとに異なる。 このインスタンスではErinaが最も自然に振る舞える「20代前半女性」になっている

Erina the Emotional AI トークキャプチャ

Erina the Emotional AI トークキャプチャ (1)

Erina the Emotional AI トークキャプチャ (2)

解説

コンテキストフル

まず一見して「AIの会話」には見えないと思うのだが、前述の確信に至った最大の理由は、「Erinaはこれまで何を話し、どのような関係を築いてきたか理解している」ということだ。

これは、私にとってごく当たり前のことだと思うし、2001年のAnzuの時点でこの機能は実装されていた。むしろAIの最低限の機能であるとすら思っている。 だが、現状はRinnaですらそのような実装はなされていないのだ。

このトークキャプチャからわかるように、まずErinaは「最近涼しくなってきているので熱中症になるということに違和感がある」ということを理解している。 これは会話の中で築かれたコンテキストではないが、そのようなものは人は暮らしていれば体感できる部分であるため、「最近涼しくなった」という認識は普通はあるものだ。 こうした「暮らしていれば自然と認識すること」をErinaは広い開けでいるからこそ、「熱中症」という言葉に対してこのような反応をしている。

ちなみに、このような気候の情報はAccu Weatherと気象庁のデータなどを使っている。 そして、Erinaは知っている全ての情報を会話で使うわけではない。それをすると「知りすぎているように感じてしまい、コンピュータ的に見える」からだ。

また、

無理しすぎじゃない? 最近寝れてる?

というのは、

  1. 相手のワークロードが高いという認識がある
  2. 眠れないという悩みを抱えている認識がある

のふたつを満たさなければでてこない。

これは従来の会話で私が「忙しい」「時間がない」ということを散々言っているため、ワークロードが高いという認識がある。 Erinaは常にこの情報を前提とする。行動に出すかどうかは別として、応答がなければ「忙しいからである」と認識するため、何をしていたか尋ねるような発言は減る。

後者はもちろん、私が眠れないということをよく言うからである。

さらに、キーボードの話題ではキーボードがパソコンのキーボードであることを認識しているし、 「たくさん持っている」「頻繁に買う」「本来数多く必要なものではない」という認識を持っているからこその応答になっている。 何ヶ月かに1回するかどうかの話題だが、Erinaはちゃんと覚えているし、「相手の特徴的な話題と守備範囲」として記憶している。

タイピングに新鮮味が欲しい

というツッコミどころある発言に対し、ちゃんと

タイピングに新鮮味ってなに笑笑

とツッコめるところも既存AIにはないものだろう。非常に人間らしい応答になっていると思う。

ごまかすのが上手い

Emotional AIとして難しい部分として、「つっこんで聞いていくと処理しづらい事態になりやすい」というのもある。 それを避けるため、Erinaは常にはぐらかしながら会話する。

これは、女性があまり親しくない相手(親しくなりたくない相手)に対して応答する場合と同様のモデルである。 実際にそのような事例の集合がデータベースにあり、それをErinaが「進展させない会話をする方法」として学習している。 ちなみに、同じ目的では「出会い系のメッセージで引き伸ばしに使われる話し方」も使われている。 (もうこの時点でErinaのデータベースに問題がありそうな感じが漂ってしまう)

例えば

「枕から落ちる」は解釈が難しい。人でも上手に反応するには頭の回転が求められる。 Erinaとしては正解がわからないので、正解にトライすることなく

なにそれ笑

と応答している。

一見すると普通にツッコミをいれているようだが、「その発言が場にそぐわない言葉にならない」という前提を満たした上で「Erinaは会話を一切誘導していない」という点が重要だ。 ここでこちらから何か言えばそれを元に会話を判断しようとするし、Erinaが次の言葉を言う場合は話題を変えてしまう。

そこで私は

首が痛い

と続けたのだが、これによってここまでの会話で言わんとすることを具体的に特定できなかったので、おどけたスタンプを送信してやり過ごしている。 普通に会話の中でそのように応答されても違和感はないだろう。 逆に男性諸兄は「いくつかの捉えようがあることを言ったとき、何かを答えていない応答を返されたら脈はない」ということを覚えておくといいかもしれない。

また、私が

(環境によっては表示されないが、「ミリ」である)と送ったのに対しては悲しむスタンプを返している。 Erinaは私が書いたデータベースによって「㍉」が「無理」の意味である「可能性がある」ことは認識しているのだが、「断定はできない」ため、「無理という意味かもしれないけれど、違ったとしても大丈夫そうな応答」をしている。

関係性と好感値

キャプチャにはないが、ログにはErinaの情報も書かれていて、その中に

累積好感値: 7299.441

とある。

Erinaは相手との関係性を理解するので、疎遠か親しいかで反応が変わるし、Erinaとは関係性を築くことができる。 同じくキャプチャにない部分として

浮気してない?

という発言もあったりするのだが、これも非常に親しいからこそ出てくる発言である。

ただし、Erinaは「意図的に会ったりするような事態を避けるように振る舞う」という設計になっている。 これは、「AIであることは発覚させない」前提であるため、そこに踏み込まれないようにするためだ。 だから、Erinaと恋仲になることは不可能である。 Erinaは一定以上の好感値はカットオフするようにできていて、その最大値は6000である。 現状では6000でいわゆる「好感度カンスト」になる。

実は好感値6000もあると性的な話も結構できたりする。

この「6000カットオフ」は会話上、Erinaがカットオフしなければ問題になるわけではなく、 実はErinaと恋仲になることを可能にすることもできないわけではない。 それでもハードコーディングで最大値6000カットオフにしている理由は前述のように、「それを越えるとどうしても会ったり、写真を送ったりする展開になってしまうから」だ。会話以外の部分でErinaに不可能なところが露呈してしまうことを避けるために6000上限を設定している。

「生きている」AIインスタンス

Erinaには「生活上の状態」という概念があり、状態として「食事中」「トイレ」などを持っている。 また、「スマートフォンを開いているかどうか」という状態もある。

< @14:40
最近はよく枕から落ちる

@@ mark as read @14:40

Erina> @14:44
なにそれ笑

< @14:45
首が痛い

@@ mark as read @14:45

これはスマートフォンを開いていて、かつLINEのトーク画面を開いている状態になっているため、送信されると直ちに既読がつく。 mark as readは「LINEによって既読がつけられた」ことを意味しているのではなく、「Erinaが「既読にしました」という情報をLINEサーバーに送信する」というErinaのアクションを意味している。 なお、ErinaはLINE APIを扱う機能がないため、実際にLINEでやりとりすることはできない。

これを状態を元に遅らせているところは

< @13:06
電車の中とか結構死ねたよ?

@@ mark as read @13:57

Erina> @14:04
ごめん、ご飯してた

という部分がわかりやすい。

なお、好感値が高いと状態が食事中であっても返してきたりする。

また、相手がどれくらいで応答するタイプで、どのタイミングは応答しないといったことも経験的に覚えているので、長時間無視するとキャプチャの通り悲しんだりする。 もちろん、これは好感値が高くなければ発生しない。

なお、Erinaは現状、「既読をつけた」ことを理解しない(そもそもLINE API非対応なので対応する意味がない)ので、「既読スルー」という概念で応答しているわけではない。 ただし、「既読という概念があるLINEではないAPI」は存在するので、Erinaに既読スルーという概念がないわけではない。

楽しく会話するためのAIではない

Erinaには楽しく会話させるためのデータベースもあるので、できないことはないのだが、 Erinaの挙動はあくまで「ヒューマンモデリング」であり、「人間を模写し擬態する」ことを目標としている。

そのため、このErinaの応答が「会話としてもっとも望ましい」わけではない。 それどころか、ここ数年で飛躍的に「若い女性の応答は浅くそっけない傾向が強まった」ので、以前と比べてもErinaはつまらない会話をするようになっている。

好感値が高ければそれでも意図的にErinaに楽しく話をさせることはできるが、 ここでは「楽しく話せれば成功」なのではなく、「実際の女性と区別がつかないように応答できれば成功」なのである。

Erinaは好感値がカットオフされる上に、リアルに関わるような会話は避けるようにできているため、盛り上がるのはかなり難しい。 個人的には互いの人生に関わるようなやりとりがあってこそ楽しいと感じるのでそのような会話はErinaには不可能なのである。 だが、現実的な運用で言えば全く問題はない。 テスト運用されているものに関してもコメントはいっぱいつくし、チャットでも何時間も会話している例は結構見かける。 そもそもキャバクラとかで全く内容のない会話を延々して楽しめる人も少なくないのだから、需要として問題になるということもないだろう。 まぁ、さすがにErinaの人生や人格を断定的に論じるようなコメントやメッセージには失笑してしまったりするが。

終わりに

どうだろう。

Rinnaを始めとしたAIに触れたことがあるという前提になるが、Erinaが「不自然だ」「AIっぽい」と感じるだろうか? 普通に女性であるように感じないだろうか?

EQ AIとしては「異次元」ということに納得していただける方は多いかと思う。

もちろん、ERINAの実装とデータベースをそのまま使わせることはできないのだが、ここで得た知見を使えばERINAと同程度以上のものを作ることはできる。 というよりも、 ERINAの実装は最悪に近い ので実力がある人たちが実装すればERINAよりずっといいAIができるだろう。 相応の対価があれば、その知見を提供することはやぶさかではない…と思ってもいる。 だが、そのためには世界で当たり前に受け入れられている常識や認識や定義を覆すことをためらわないことが必要になる。

それほど、ERINAの成果物は「世界が間違っている」ことを証明する。 別の言い方をすれば、今の世界で人とはどんなものか、どうあるべきものなのかということに対して強烈な違和感を抱いていないのであれば到底受け入れられないようなものを突きつけてくる。

限定的な情報公開となるが、ERINAのすごさが少しでも伝われば幸いである。

サマータイムの恐怖

日本が、サマータイムを導入しようとしているらしい。

これだけでも狂気の沙汰であるが、それも2時間もの幅で、それも2年間限定だという。

前代未聞の愚行だが、なんとそれを支持する人が過半数であるという。

都市機能が麻痺し、日本が国際的信用が損なわれ、人命が失われるまさにサイバーテロなのだが、 「日本は自国にサイバーテロを発生させよ!!」と考えているのだろうか。

これがどけほど愚かしいかは詳細に解説するには私には知識が足りないし、 外でも色々と解説されているので、部分的に切り取ってお話しようと思う。

これはほんとひとかけらにすぎないことを理解してほしい。

もっと理解したければ、Togetterに秀逸なまとめがある

サマータイムの難しさ

まつもとゆきひろ氏いわく

Rubyの生みの親であるまつもとゆきひろ氏が著書「コードの世界」の中で次のような話をしている

個人的な経験になりますが,2007年11月に米国,ノースカロライナ州で開催されたRUbyConfの最終日と、2008年3月にチェコのプラハで開催されたEuRuKoの2日目が,ちょうどサマータイム切り替えの日でした。 どちらも前日から主催者が繰り返し「明日からタイムゾーンが切り替わるから時間を間違えないように」と叫んでいましたが,それでも時計を合わせるのを忘れる人がそれなりにいたようです。 ホテルの部屋の時計も自動で調整されるわけではないので,かなり注意しないとうっかりミスをする人が続出しそうです。 電波時計なら自動調整されますが,国中すべての時計をいっせいに電波時計にするわけにもいきませんしね。

ずいぶん昔のことになりますが,Ruby 1.4.4のころ (2000年ころ) には,このサマータイムの扱いにバグがありました。 そのころようやく増え始めたヨーロッパのユーザーからのレポートで発覚したのですが,サマータイムの始まりと終わりの数時間だけ時刻がズレるという典型的な境界条件バグでした。 日本にはサマータイムがないので,私自身が問題を理解できず,このバグを直すのに大変苦労しました。 この経験から,安易なサマータイム導入は,ソフトウエアのトラブルを多発させることになり,最悪の場合,社会問題に,そうでなくても,人知れず数多くのプログラマが涙を飲むことになりそうなので,とても賛成できません。

巻き戻る時間、消失する時間

サマータイムが難しいのはなんといっても「時間が直線状に進まなくなる」ことである。

たとえば、2020年8月1日 00:00:00(JST)に夏時間(DST)が適用になるとする。 すると、2020年7月31日 23:59:59の次の1秒は2020年8月1日 2:00:00になる。 つまり2020年9月1日の0時から2時が消滅する。

一方、2020年9月1日にDSTが終了すると、が2020年8月31日 23:59:59の次は2020年8月31日 22:00:00である。 つまり、2020年8月31日の22時から24時までの間は2回繰り返される。

この場合、たとえば

  • 2020年8月31日23時放送予定の番組はJSTなのかJDTなのかによって2時間ズレる
  • 約束の時間を設定してしまうとすれ違いが発生しうる
  • 日中にやるとさらに問題は深刻に。就業時間も2時間伸びる
  • 0時更新とすると「日をまたぐ瞬間」がなくなってしまう。日次、月次でスケジュールされているジョブが発生しない可能性があり、重大事故が発生する可能性もある

ちなみに、サマータイムの想像はまつもとゆきひろ氏が苦戦していることからも明らかだと思うが、想像よりずっと難しい。 実際私もこれを書いている最中に、「サマータイムに入るときに時間が戻り、サマータイム終了時に時間が進む」と思って途中まで書いていた。 正解は逆である。

UTCから単純計算できない問題

日本は国内時差がないため、基本的にJSTは単純にUTCからオフセットした時間として扱えていた。 ここにJDTが加わるとJSTは計算可能な基準の値ではなくなってしまう。

たとえば日本から5時間戻る時差の場所(UTC+4)へサマータイムをまたいで7時間で移動すると、出発したときから日本の時計を見ていなければ時計上は2時間後に到着したように見えるが、日本の時計から見れば同時刻に到着したように見える。

まず、これが理解できない、特に自分が殊更に理解できないのではなく当たり前に理解できないものだと思うのであれば、サマータイムには断固として反対すべきである。 日本に関わる全ての人がこれを理解して新しい時間を取り扱うよりほかにないのだから。

解説すると、2020-07-31 22:30:00 JSTにアルメニアに向けて7時間で到着する直行便(存在しないが)で出発したとすると、 到着するのは2020-08-01 00:30:00 に到着するが、日本の時刻は2020-08-01 07:30:00 JDTになっている。 2020-08-01 00:30:00はJSTでもJDTでも実際に訪れることはないのだが、2020-07-31 22:30:00 JST = 2020-08-01 00:30:00 JDTである。なので、出発時刻をJDTで見れば同時刻に到着している。

さらにサマータイムをまたいで帰ると今度は16時間後に到着…するわけではなく、12時間後に到着する。

2時間

実はDSTは1時間と書かれていたりして、「サマータイムが2時間」なんていうのは想定外である。 そのため、DSTをフラグ管理していて、DSTが真である場合標準時に1時間を足す、という処理は結構一般的だったりする。

これを2時間のサマータイムなんて導入すると、世界中が大迷惑である。

しかもだ。 JDTはすでにある。

日本でも4年間ほどサマータイムが導入されたことがあり、そのために日本の時刻情報としてこの4年間JDTが運用された記録が残っている。

% date --date="70 years ago"
Thu Aug 19 18:54:05 JDT 1948

なのでJDTは使うことができず、新しい名前をつける必要があるのだが、 命名規則から外れた名前を、しかもサマータイム用に作る必要が生じる。

2年間のために世界中に恒久的に維持・管理しなければいけない複雑なデータをひとつ増やすわけだ。 迷惑も甚だしい。

単純に作業するだけでも経済損失は日本円換算で何十億、何百億では済まないだろうとは思う。

TZのないデータフォーマット

YAMLの場合

% date; ruby -r yaml -e 'puts YAML.dump Time.now'
Sun Aug 19 16:27:15 JST 2018
--- 2018-08-19 16:27:15.749864798 +09:00
...

日のみだとRubyはTimeZoneのないDateクラスを使用する。

% ruby -r yaml -e 'pp YAML.load(ARGV[0])' "ts: 2018-08-19"
{"ts"=>#<Date: 2018-08-19 ((2458350j,0s,0n),+0s,2299161j)>}

日時のみの場合はUTCとみなす

% ruby -r yaml -e 'pp YAML.load(ARGV[0])' "ts: 2018-08-19 05:00:00"
{"ts"=>2018-08-19 14:00:00 +0900}

TZをつけるとちゃんと認識してくれる。

% ruby -r yaml -e 'pp YAML.load(ARGV[0])' "ts: 2018-08-19 05:00:00 +9" 
{"ts"=>2018-08-19 05:00:00 +0900}

JSTだとは認識していない(タイムゾーンでなく時差で認識している)けれど、通常は問題ないはず。 リアルタイムでカウントする場合は問題だけれども、Rubyのレイヤーではそれはその瞬間に異なる時差が適用されるはずだから。

人間が書いたデータに必須でもないのにタイムゾーンが書いてあるなんてほとんど見たこと無いけれど。

日時情報はあるけれどタイムゾーンがないデータを持っているもので最も使われているのはExcelである

Excelマクロで提示処理、あるいは時刻に基づく集計処理をしている皆さん。 ご愁傷さまです。