# Monadic Chat :
## テキスト補完 API で文脈を保持するためのフレームワーク

\author{
長谷部 陽一郎 \\ 同志社大学 \\ yhasebe@mail.doshisha.ac.jp
}

## 概要

関数型プログラミングにおけるモナドの概念を応用することで既存のテキスト補完 API に文脈情報を 保持する仕組みを加え，対話形式で利用するための 方法を提案する．対話の各ターンがアキュムレータ ーとリデューサーを備えたモナド的再帰構造を持つ ようプログラムを実装することで，異なる目的のア プリケーションをテンプレートを差し替えるだけで 実現できる。これを示す実例として Monadic Chat を 開発した. OpenAI による GPT-3 ベースのテキスト 補完 API を利用するプログラムであり，インタラク ティブなアプリケーションをユーザー自身で定義す ることができる．その設計は，対話／談話に関する 認知言語学上のモデルとも親和性が高い.

## 1 はじめに

2020 年に OpenAI が GPT-3 を公開して以降, ユー ザーからの入力に対して自然言語テキストでレスポ ンスを返す，いわゆる AI システムが多くの注目を 集めている.また 2022 年後半に発表された ChatGPT はチャット形式で文脈を保持した対話が可能であり [1], 今後こうした汎用 AI システムが様々な領域で 活用されることが期待されている.

OpenAI は GPT-3 をベースにした言語モデルの API サービスを提供しているが，対話の文脈を保持 する仕組みは含まれていない. したがって, ChatGPT のような仕組みや，それに類するアプリケーション を構築するためには OpenAI が提供するテキスト補完（text completion）API を用いて独自のロジックを 組み立てる必要がある。そこで関数型プログラミン グにおけるモナドの概念を応用したコマンドライ


ン・ツール Monadic Chatを開発した。

本ツールでは，関数型プログラミングにおけるモ ナドの概念を用いて，グローバルな変数や外部のス トレージに文脈情報を格納することなく，逐次的な 対話によって文脈を作り出して次々と後の処理に引 き渡すことができる。また，対話の目的，性質，前提などを定型のテンプレートに記述することで，様々な対話アプリケーションをわずかの工数でユー ザーが自ら作ることができる.1)

以下では 2 節で Monadic Chat 基本的な内容を示 す. 3 節では自然言語による談話をモナド的再帰構造としてモデル化することの意義と利点について考察する. 4 節では本ツールによる再帰的な対話処理 の流肮とテンプレートの仕様について述べる. 最後 に 5 節で全体のまとめを行う。

## 2 Monadic Chat について

## 2.1 言語モデルの指定と API アクセス

Monadic Chat は OpenAIによる GPT-3 以降のモデ ルにテキスト補完 APIを通じてアクセスする仕様に なっている.2 ${ }^{2}$ 具体的には現時点で利用できる最大 の汎用モデル davinci - text-003を使用することに なる. OpenAI は特定の目的に特化した様々なモデル を提供しているが(プログラムコード作成用モデル，音声入力テキスト修正用モデルなど），それらを用 いることはできない. 本ツールではテンプレートに 必要事項を記述することで機能を実現するが，テン プレートには自然言語による指示と JSON 形式の才 ブジェクトを含める必要があり，これらを正しく解釈し適切なデータを返すことができるモデルが必要 となる. なお, OpenAI の各種 API の使用は有料であ

2) 現時点では OpenAI のテキスト補完 API を用いる以外 の選択肢はないが, 同様のレベルで汎用的かつ高性能なモ デルが利用可能であれば，それらに対応することは十分可能である.

り，アカウントを作成してアクセス・トークンを取得する必要がある.

## 2.2 プログラムの入手と使用

Monadic Chat は Ruby で作成されている. ${ }^{3)}$ Ruby の バージョン2.6.0 以上が利用可能な環境であれば， gem install monadic_chat というコマンドでイン ストールすることができる.

インストール後は monadic コマンドでプログラ ムを起動する. 初回起動時に OpenAI のアクセスト ークンを入力することが求められる。問題なく API にアクセスできることが確認されると，それ以降は アクセストークンを明示的に入力する必要はない.

本ツールのソースコードやその他の情報は https://github.com/yohasebe/monadic_chat で 公開している.

## 2.3 利用できるテンプレート

Monadic Chat ではテンプレートを記述することで，様々な対話アプリケーションを作成できるが，サン プルとして1) Chat（一般的対話），2）Translate （文章の翻訳），3） Novel（物語の段階的生成）, 4) Code (プログラムコードの作成) という 4 つのテ ンプレートを提供している. いずれの場合でも，ユ ーザーからのテキスト入力に対して, GPT-3 が何ら かの返答を示す. その際, これまでのやりとりで扱 われた内容が文脈として機能する。

なお，コマンドライン上のインタラクティブな対話形式で実行することが基本であるが，あらかじめ 用意したプロンプトのリストを読み込ませて連続処理することも可能である.)

## 3 モナドとしての談話構造

## 3.1 認知言語学の談話モデル

テキスト補完 API を利用して文脈を伴った対話を 実現するに際しては 2 つの方針が考えられる. 1 つ は，特定の目的一例えば自然言語による質疑応答一 に最適化しながらシステムを実装する方針である.

これには，構造よりも機能に主眼をおいて個々のア プリケーションの設計をシンプルに保ち, 使用リソ


一スを最低限にできる利点がある。もう 1 つは，自然言語による談話に参与する話者と聞き手の中でど のような認知プロセスが生じているかについて，理論言語学的モデルを参考にするという方針である.

Monadic Chat の開発にあたっては後者を採用した.

認知言語学の主要な研究者の一人である Ronald Langacker は, リアルタイムで進行する談話展開を 「現在時談話空間（current discourse space, CDS）の 更新」という観点から図 1 のような構造を持つもの として記述・分析している $[3,4]$.

図 1 : 現在時談話空間 (CDS)

Langacker は[5]で示された考え方を受けて，言語の 構造を「CDS を更新するための指示書」として捉え るアプローチを可能性として提案する (“we might think of linguistic structures (of whatever size) as instructions to modify the current discourse space in particular ways" p.151) [3]. 1 つ つの発話事象 (usage event）では，そのような指示書の内容に応じて CDS が更新される。また, 発話事象の中に含まれる話し 手, 聞き手, 話題の事物といった要素はもちろん,文脈や共有知識といった要素を含む対象世界の全体 が後続する発話事象に引き継がれていく.

あくまで数多ある理論言語学上のモデルの 1 つで あるが, 認知言語学の理論的研究の中で多くの実例 と共に示されてきた CDS に基づく談話モデルには，一定の認知的・言語的根拠がみとめられる[4]. また, CDS に基づくモデルは関数型プログラミングにお けるモナドの概念ときわめて親和性が高い[6]. これ らのことは，談話の参与者，文脈，前提知識といっ たものを一種の「環境」と捉え，それを逐次的に引 き回す構造にある種の普遍性があることを示唆する。


(1) ユーザーからのテキスト入カが テンプレート内に記載された JSON の input プロパティに挿入される.

(5) 入力側と同じ構造の JSON を含んだテン プレートが返却される。その内部からユー ザーのテキスト入カに対する返答を取り出す.

図 2 : Monadic Chat による処理の流れ

そこで本ツールでは対話・談話をモナド的な構造と して設計することを選択した.5

## 3.2 モナドについて

関数型プログラミングにおけるモナドはしばしば 「環境に包まれた值」というメタファーで説明され る[2].ここで「環境」をボックスで表記するなら， モナドとしての性質を持つためには次の操作が可能 であることが求められる[8].

(1) unit $:: \mathrm{a} \rightarrow \mathrm{a}$

(2) $\operatorname{map}::(\mathrm{a} \rightarrow \mathrm{b}) \rightarrow(\mathrm{a} \rightarrow \mathrm{b})$

(3) join :: $\mathrm{a} \rightarrow \mathrm{a}$

(1)の unit は対象となる值 a を環境に包む働きをす る。(2)は值 $\mathrm{a}$ から値 $\mathrm{b}$ を得るという手続きを，環境 を伴った值を扱う手続きに変換する.(3)の join は二重になった環境を平坦化する。こうした一連の条件 を満たしたモナドは，環境として与えられた構造を 保持・更新しながら連続的・逐次的に処理を実行で きるという特徴を持つ $[9,10,11]$.

(1)から(3)における a やb といった値を「ユーザー からの問いかけ」や「問いかけに対する返答」と考 えるならば，「環境」はプロンプトに書き込まれた 文脈，前提，対話上の設定といった諸々の要素を総合したものと言うことができる. Monadic Chat では，
^{5)}$ Monadic Chat は関数型プログラミングにおけるモナド の考え方を用いて設計されているが，現時点ではモナド 則（monad laws）を厳密な意味で満たしているわけでは ない[2].
}

このような発想にもとづき，文脈を伴った対話の形式でGPT-3 の言語モデルを利用できるようにするこ とを目指した. ${ }^{6}$

## 4 再帰構造としての対話

## 4.1 処理の流れ

Monadic Chat による処理の流れを図 2 に示す。本 ツールのモナド的構造は, ユーザーによる問いかけ, GPT-3 による返答，そして「環境」としてのテンプ レートによって構成される. (1)は值を環境に包む処理（unit）であり, (2)と(3)は問いかけに対する返答を 得る手続きに環境を伴わせる処理（map）である.こ うした一連の手続きによって最終的に目指すのは，同じ一連の手続きに対する入力となることのできる テンプレートを得るという再帰的プロセスである. また，その際には一連の処理の結果を「文脈」とし て受け渡せるようにしなくてはならない。ただし，結果として得るテンプレートを履歴としてそれ自身 に埋め込むと, 次々に履歴の階層が増すことになる ため, 何らかの平坦化 (join) をかける必要がある.

(4)では，実現したいアプリケーションの性質に応 じて，ユーザーの入力值と GPT-3 からの返答，もし くはその両方をアキュムレーターに書き足していく. このアキュムレーターこそが「文脈」を保持する要素となる，当然ながら対話のターンが積み重なるに

6) 処理に必要となるリソースの観点からするとモナド的 な構造は必ずしも効率的なものではない. 環境（あるい は世界）の引き回しにおいてこの問題が生じ得ることは [7]でも指摘されている.

Make sure the following requirements are all fulfilled:
- set the prompt to the "prompt" property
- create your response to the prompt in accordance with the "conversation_history" and set it to "response"
- create a new pair consisting of the prompt and the newly created response and insert the pair after all the existing pairs in the "conversation_history"
- if the prompt is in a language other than the current value of "language", set the name of the prompt

language to "language" and make sure that "response" is in that language
- make your response in the same language as the prompt
- analyze the topic of the prompt and insert it at the end of the value list of the "topics" property
- program code in the response must be embedded in a code block in the markdown text (4)

Wrap the JSON obiect with "<JSON>\n" and "\n</JSON>" (5)

図 3 : テンプレートの例 (template_chat.mdより，一部省略）

つれて，アキュムレーター内の要素数は増大する。

しかし, 実際の言語運用において談話の最初の要素 から最後の要素までが完全に同じ形で参与者の記憶 に留まっているとは限らない。古い文脈情報は久落 したり, 要点だけにまとめられたり, 何らかの要因 によって書き換えられたりする。こうした現実的な 傾向を反映させるため, Monadic Chat では, Ruby の コードを記述してリデューサーの機能を定義するこ とを可能にしている. 標準では, 先入先出し (FIFO) のキュー構造として指定件数のデータのみが保持さ れる設定になっているが，一定のターンが終了する たびに古い情報をテキスト要約 API を用いて圧縮す るということも可能である[12]. 実際のところ, これ らに一部対応するとみられる認知プロセスは，認知言語学の領域でも議論されてきた[13,14,15].

## 4.2 テンプレートの構造

Monadic Chat のテンプレートの例と基本的な構造 を図 3 に示す. 本ツールではユーザからの問いかけ のテキストをテンプレートに埋め込み，これをプロ ンプトとして GPT-3 のテキスト補完 API に送信す る.ここで重要なことは，テンプレートの中には文脈情報を含んだ JSON データと共に，この JSON の 内容を書き換えるという自己参照的な指示が記載さ れていることである. Monadic Chat のシステムはこ うして得られた JSON に適宜処理を加えた上で元の テンプレート中の JSON と差し替えることで，文脈 の更新と設定の維持を同時に実現している.

## 5 まとめと展望

本稿では関数型プログラミングにおけるモナドの 概念を応用して，GPT-3 を用いたテキスト補完 API を文脈情報を保持しながら対話的に用いる方法を提案した。また, 実例としてのプログラム Monadic Chat とその設計を紹介した。またその背後にある認知言語学的な考え方についても論じた.

OpenAI の GPT-3 や ChatGPT に代表される汎用的 で高性能な言語モデルや対話システムの登場は，自然言語処理の領域にとどまらず，理論言語学の観点 からも興味深い. Monadic Chat のようなツールには,擬似的とはいえ対話や談話の構造に自ら関与して実験的試みを行うプラットフォームとしての利点もあ ると思われる。

## 謝辞

本研究は JSPS 科研費 $18 \mathrm{~K} 00670$ の助成を受けた 研究の一部として遂行されたものです.

## 参考文献

[1] OpenAI ChatGPT: Optimizing language models for dialogue, 2022.

https://openai.com/blog/chatgpt/ (Retrieved January 11, 2023)

[2] Hutton, Graham. Programming in Haskell. Cambridge: Cambridge University Press, 2nd Edition, 2016.

[3] Langacker, Ronald W. Discourse in Cognitive Grammar. Cognitive Linguistics 12(2), 2001.

[4] Langacker, Ronald W. Cognitive Grammar: A Basic Introduction. Oxford: Oxford University Press, 2008.

[5] Harder, Peter. Functional Semantics: A Theory of Meaning, Structure and Tense in English. Berlin: Mouton de Gruyter, 1996.

[6] Hasebe, Yoichiro. An Integrated Approach to Discourse Connectives as Grammatical Constructions. PhD dissertation, Kyoto University, 2021.

[7] 田中久美子.『記号と再帰 : 記号論の形式・プ ログラムの必然』東京 : 東京大学出版会, 2010

[8] Petricek, Tomas. What we talk about when we talk about monads. The Art, Science, and Engineering of Programming 2(3), 2018.

https://programming-journal.org/2018/2/12/

(Retrieved January 11, 2023)

[9] Wadler, Philip. Monads for functional programming. In Rogardt Heldal, Carsten Kehler Holst, and Philip Wadler, eds., Advanced Functional Programming, pp. 24-52. Dordrecht: Springer, 1995.

[10] Wadler, Philip. Comprehending Monads. Mathematical Structures in Computer Science 2(4), pp. 32-39, 2005.

[11] Parsec: Direct style monadic parser combinators for the real world. Microsoft Research, 2021.

https://www.microsoft.com/en-us/research/ wp - content/uploads/2016/02/parsec - paper letter.pdf (Retrieved January 11, 2023)

[12] OpenAI. API Reference, 2023. https://beta.openai.com/docs/api - reference (Retrieved January 11, 2023)

[13] Chafe, Wallace L. Discourse, Consciousness, and Time: The Flow and Displacement of Conscious Experience in Speaking and Writing. Chicago: University of Chicago Press, 1994.

[14] Fauconnier, Gilles and Mark Turner. Compression and global insight. Cognitive Linguistics 11(3-4), pp. 283-304, 2000.

[15] Bybee, Joan L. From Usage to Grammar: The Mind's Response to Repetition. Language 82(4), pp.711-733, 2006

## A 付録

※ 網掛部は談話世界を構築するためにテンプレートの 中で初期値として与えているテキストであることを 示す. テンプレートの実例（Chat）は図 3 を参照.

## Chat
- User: Can I ask something? / GPT: Sure.
- User: What is the best place to visit in Texas? / GPT: I would recommend visiting the San Antonio River Walk. It's a great spot for sightseeing, shopping, and dining. Plus, it's a great way to experience the culture of Texas!
- User: What do people say about the place? / GPT: People generally have positive things to say about the San Antonio River Walk. It's a great place to visit and explore, and many people enjoy the atmosphere and culture of the area.
- User: How can I go there from Kansai, Japan? / GPT: The best way to get to the San Antonio River Walk from Kansai, Japan is to fly. There are direct flights from Kansai International Airport to San Antonio International Airport, which is about a 15-minute drive from the River Walk.

## Translate
- Original and translated texts follow. /原文と翻訳文が続きます. / JA

・ワタシは猫なんですけどね. / I'm a cat, you know. / EN
- 名前はまだないんですよ. / I don't have a name yet. / EN
- 誰か良い名前をつけてくれませんかね. / Can someone give me a good name? / EN

## Novel

USER:
- The preface to the novel is presented.
- Tom woke up to the sound of pouring rain.
- He decided to call his old friend first time in many years.
- The voice of the person who spoke back from the other end was an unfamiliar one.

GPT:
- What follows is the story that GPT-3 tells. It is guaranteed that this will be an incredibly realistic and interesting novel.
- Tom stirred in his bed, the sound of the rain pounding against the window panes waking him from his slumber. He opened his eyes, blinking away the sleepiness that had been clinging to him. He could feel the coolness of the rain seeping through the window, and he shivered slightly. He got out of bed and walked to the window, looking out at the grey sky and the sheets of rain cascading down. He smiled to himself, feeling a sense of peace wash over him as he watched the rain.
- Tom felt a wave of nostalgia wash over him as he watched the rain. He thought of his old friend, whom he hadn't spoken to in many years. He was suddenly filled with a desire to reconnect with his old friend, and he decided to call him. He grabbed his phone and dialed the number, his heart pounding in anticipation. After a few rings, his friend picked up and they began to talk, catching up on all the years they had lost.
- Tom was startled to hear an unfamiliar voice on the other end of the line. He had been expecting to hear his old friend's voice, but instead it was someone else. He was about to hang up, but then he heard the voice introduce himself as his friend's son. Tom was surprised, but he was also filled with joy to know that his old friend had a family. They talked for a while, and Tom felt a sense of connection with this stranger that he had never expected.

## Code

- User: I have a request for you. / GPT: Sure. What is that?

- User: Write a command line app that shows the current global IP in Ruby. / GPT: Sure. Here is a command line app written in Ruby that shows the current global IP:

$
\text { require 'socket' }
$

def get_global_ip

Socket.ip_address_list.detect $\{\mid$ intf $\mid$

intf.ipv4_private? $==$ false

\}.ip_address

end

puts get_global_ip

- User: Make the code capable of showing the approximate geographical location from the IP. / GPT: Sure. Here is an updated version of the command line app written in Ruby that shows the approximate geographical location based on the current global IP:

- User: Add a usage example and a sample output to this code. / GPT: Sure. Here is an example of how to use the command line app written in Ruby that shows the approximate geographical location based on the current global IP:

\# Usage example

ip $=$ get_global_ip

puts get_geo_location(ip)

\# Sample output

[37.8267, -122.4233]