React.js: The Documentaryで振り返るReact普及の歴史

www.youtube.com

Meta(当時Facebook)のReact Core Teamの主要人物たちに直接インタビューしたドキュメンタリー動画

タイムライン

2012年まで

最初はFacebook社内でReactが普及するまでの道程。

当時世の中的にはクロスブラウザの解決策はjQueryに落ち着き、モバイルアプリ化の流れでAPIサーバーとViewは切り離される傾向にあり、JavaScriptのクライアントサイドで大きいアプリケーション作るためにMVCフレームワークとか取り入れないとね〜という雰囲気だった

Facebook社はマーク・ザッカーバーグHTML5に賭けていた頃*1にBolt.jsというFacebook版Backbone.jsを開発していた

広告プラットフォームのコードは当時Bolt.jsを中心に構成されていたが、Jordan Walkeが関数型プログラミングのアイデアを取り入れ改善しようとした

これがReactの元になっている

先ずReactをNewsFeedのウィジェットに部分導入した

その後Pete Huntが参加し、InstagramのWeb版に導入

移行プロジェクトをするかどうかでめっちゃ揉めたけど、広告プラットフォーム自体も既存のBolt.jsから新興のReactに全面移行

2013年

次はFacebook社外に展開する。開発チームはReactのOSS化を押し進めた。

JS Conf USでReactを大発表したら「JSXがキモ過ぎる」と話題に

www.youtube.com

開発チーム意気消沈

JSConf EUで次鋒Pete行きます

www.youtube.com

この辺りからKhan AcademyのエンジニアやClojureScript作者*2など一部関数型プログラミング愛好家の間では好評価

着実にフォロワーが増えはじめる……

2014年

この頃から日本のコミュニティでもアーリーアダプタの間で話題になっており、よく記事を見かけた

他方、Flux ArchitectureなどReactを実践する為の話題に発展していった

www.youtube.com

2015年

React Nativeリリース

www.youtube.com

NetflixAirbnbYahoo!GitHubなどがReact使ってるよと表明していたのもこの時期

React界隈で熱心にハックしていたDan Abramovという若者がReact EU ConfでReduxを発表

www.youtube.com

Hot Reloading+タイムトラベルデバッグの概念実証をして界隈がザワつく

そのまま面接してCore Teamにジョイン

2016年以降

中国や日本ではコミュニティの先行したVueの方が多く使われていた時期もあったが段々Reactの採用が増えていった

感想

以下の点に関心を持った

開発現場での問題を解決するために生まれた技術であること

組織が計画的に研究して生み出されたイノベーションではなくて問題と個人の裁量が先にあり、それぞれの人が協力して泥臭くできた結果というのが素晴しいと思った

広告プラットフォームはサルたちの狂宴 下 ――フェイスブック乱闘篇という本などからも分かるとうりFacebookにとってのキャッシュエンジンで、そこの開発を数ヶ月止めてReactに移行するするか否かを現場のエンジニアが判断して、CTOは「中長期的に良い判断をしてくれ」とだけ言って見守っているのがすごい。

また実際に起きている問題を解決するものなので、アーリーアダプタ以下の我々が持つ「ユーザーがどれぐらいいて、どのぐらい将来性のある技術なのか」という類の視点ではなくて、最初から本番環境投入するために開発されておりイノベーターの視点を知ることができた。

新しい概念を普及させてWeb開発の考え方ごと変えたこと

Reactが作るの新しい概念が受け入れられることに注力している描写が多かった

確かにReactは当時からしたらかなり受け入れづらい開発手法だった

今のような駆け出しエンジニアがReactを通じて関数型プログラミングのエッセンスを意識せずに体得する状況になるとは思っていなかった

今の地位にくるまでに、Reactチームはドキュメンテーション、エラーメッセージ、開発ツール、コミュニティ活動などをインクリメンタルに行っていたようだ

ReactはjQuery+Backboneからの置き換えの側面が強かった

  1. jQuery普及
  2. 大規模jQueryアプリケーションとしてBackbone+CoffeeScript(Marionette, Chaplin)が導入される
  3. 一方AngularJS等のデータバインディング系がjQuery Viewの代替としてが注目される
  4. jQueryが役目を終え、Angular, React, Vue三兄弟の状況になる
  5. Backboneで構成していたModel-Controller部分もViewライブラリ系と統合されるようになる

2014年末に発刊されたJavaScriptエンジニア養成読本にはAngularJSやBackboneが特集されているが、Reactはまだ出てこない。

この頃に現場で導入の進んでいたのはBackboneの方だったというのが分かる。

FacebookJavaScriptコミュニティの関係

Facebookは当時JavaScript界隈の有名人を引き抜いてきてWeb関係ないことをやらせてる——とJavaScript系のコミュニティから嫌われていたらしい

FirebugのJoe HewittがiOSアプリフレームワークのThree20作っていたような時代のことだと思われる

確かにMozilla出身の人が何人か居るようだけど…… よく覚えてない

Reactリリース時の反応

僕ははじめてReactを見た時はHipHopとかThriftのようなFacebookクラスのスケールの現場のみが必要としている変態なぞ高度技術ぐらいに受け取ってしまっていました

日本のコミュニティではバーチャルDOMで魂が震えたり*3、なぜかOOP vs FP宗教戦争でQiitaが燃えたり関係ない場外乱闘も発生していた(何だったのか)

登場人物紹介

Jordan Walke

github.com

  • 当時広告チームのエンジニア
  • Reactのオリジナル作者とされる人
  • JavaScript Jabber #146 によるとReact Nativeもvjeuxといっしょに中心になって開発していたようだ
  • 動画には出演を断わったのが出て来ない
  • Metaは2021年に退職してる

Pete Hunt

github.com

Christopher Chedeau

github.com

Tom Occhino

github.com

  • Product Infrastructure Teamのボス
  • 今はVercelのVPoEになってる
  • JS Conf 2013でのReactのOSS化、F8 2014でのFlux発表、React.js Conf 2015でReact Native発表の動画を見ると全部ホストをしている

Shane O'Sullivan

github.com

  • SOS
  • Dojo Toolkitのコミッター
  • Bolt.jsを開発していた

Paul O’Shannessy

github.com

Jing Chen

github.com

Sebastian Markbåge

github.com

  • MooToolsやってた人
  • この人も大量にReactにコミットしている
  • Vercelに転職した

Sophie Alpert

github.com

  • Khan Academyの数学問題のエディタでReactを導入した
  • その後React Core Teamにジョイン

Dan Abramov

github.com

  • Reduxの作者
  • Reactのコードを一番書き換えてる現プロジェクトの中心人物

Andrew Clark

github.com

  • Dan Abramovと共にRedux以降のReactの開発を支えた人
  • Vercelに転職した

コミュニティ

David Nolen

github.com

Netflix

参考文献

ChatGPTと英会話するためのツール

PCの場合VoiceWaveが使え、スマホの場合Bingアプリのチャット機能が対応している。

ツールの選び方

非公式なブラウザ拡張は大量にあるので選ぶ時のポイントをあげる。

ユーザー数が多く、怪しい拡張でないか

この部分の大小を比較する。

ユーザー数が多い=安全ということは決してないのだけど多いと僕のようなイチイチ中身を調べて使うおたくが紛れ込む確率が上るので怪しい動作をしていたらツッコミをうける。

中身を見る時は拡張IDから以下を探す。

find ~/Library/Application\ Support/Google/Chrome/Default/Extensions -name baahncfnjojaofhdmdfkpeadigoemkif

音声出力に対応しているか

音声で入力できますという機能だけを持つものが結構あって会話には使えないのでインストール前に確認する。

VoiceWave

VoiceWaveは音声入力の確定を自動、キーワード、手動から選べる点が便利だと思う。

入力のみ音声、出力のみ音声。という使い方もできる。

イヤホンではなく外部スピーカーとマイクで両方使うと自分の発話を自分で聞き取って返事するポンコツロボットみたいな挙動をする。

ChatGPT's voiceはいくつか試して名前が強そうだからぐらいの理由でGoogle US Englishにしたがそんなに違いは分からない。ブラウザが持ってるエンジンを呼び出してるだけだと思う。

エンジンの検知がうまくいかないとゴノレゴ音声みたいなものが合成されてそれはそれでおもしろい。

text to speechは機能として安定しなくて時々動かなくなったりするんだけど、これは実装したことあるから知ってるんだけどブラウザのAPI自体が慎重に使わないとすぐ死んでしまう品質だからであり拡張開発者は大変である。動かなくなったらブラウザ再起動して。

補助ツール

ChatGPT英語例文自動添削プロンプトで公開されているテキストを最初に挿入するとChatGPTに英語の指導者としてのロールを与えられる。

Bingアプリのチャット機能

音声での会話は一応できるんだけどWeb検索をはさむのでテンポが遅い。

他のツール

余談

インターネットがご家庭に普及しはじめた2000年頃に「コミュニケーション苦手な人でもテキストなら敷居が低いよね」という感覚があったのですが僕は「テキストでも苦手だが????」というスタンスでした(例えばMMORPGでパーティを組めない)。

これと似たように「AIとの会話なので気軽」という感覚に対して「AIのと会話すら苦手(つまりはバーバルコミュニケーション全般ということですが)」という人もこれから出てくるのではないかと思いました。人類の進化は奥深いですね。

人間が英文を読解することに言語生成AIを使いたい

英語のコンテンツを読むだけならDeepL等ですぐ目的を果せるのだけど翻訳ツールに頼っているとライティングなどの人間側の処理性能は上がらないし、下り坂を補助輪付き自転車で下っているだけの感覚がある。我々は上り坂も進みたい(このはてしなく遠い坂をよ… )。

以前Rubyコミッタの人か誰かが英文をS式で表現して正確な意味を解説しているのを見かれてなるほどね(不理解)と思ったんだけど、理解してないと変換できないなと感じた。

なのでこれをChatGPTにやってもらうことで翻訳ツール+αなUXにならないかなぁと考えている。

例えば「Training Language Models with Language Feedback」の概要テキストに対してこういう指示を付けてみる。

Bullet the grammatical structure of the following sentences in a tree.
To make it easier to understand the meaning.
—
{text}

S-PP-NP-VPのような記法は句構造文法というものらしい。SVO型ではない。調べてみると言語学の沼が深そうだったので地道に学ぶしかない。

むしろこの分野に詳しい人に何か良い方法ないかを聞いてみたい。

TwitterでフォローしていいかどうかもGPTに決めてもらう世界線

必要性が不明の生成画像: https://www.bing.com/images/create

TwitterとOpenAIのAPIを繋いで評価を自動化します。

#!/usr/bin/env python

import os
import sys

import tweepy
from langchain import LLMChain
from langchain.chat_models import ChatOpenAI
from langchain.prompts import HumanMessagePromptTemplate, SystemMessagePromptTemplate, ChatPromptTemplate

# フォローしたいアカウントのタイプを定義する
preferences = "\n".join([
    "創造的な性格。",
    "新しいものが好き。",
    "建設的な発言が多い。",
])

username = sys.argv[1]
oauth2_bearer_token = os.environ['TWITTER_BEARER_TOKEN']

auth = tweepy.OAuth2BearerHandler(oauth2_bearer_token)
api = tweepy.API(auth)

tweets = api.user_timeline(screen_name=username)

user = tweets[0].user
user_dump = str({
    'id': user.id_str,
    'name': user.name,
    'screen_name': user.screen_name,
    'location': user.location,
    'description': user.description,
    'url': user.url,
    'followers_count': user.followers_count,
    'friends_count': user.friends_count,
    'listed_count': user.listed_count,
    'created_at': user.created_at,
    'favourites_count': user.favourites_count,
    'verified': user.verified,
    'statuses_count': user.statuses_count,
    'lang': user.lang,
})

tweet_texts = "\n".join([t.text for t in tweets])

messages = [
    SystemMessagePromptTemplate.from_template(""""tweetの内容を分析してuserがどのような人物なのかを分析してください。
score: preferencesに一致するかを1~5で評価してください。
explain: scoreの理由を説明してください。

preferences:
{preferences}

結果をscore, explainの順で出力してください。 
"""),
    HumanMessagePromptTemplate.from_template("user:\n{user_dump}\ntweet:\n{tweet_texts}"),
]

chat_prompt = ChatPromptTemplate(input_variables=['preferences', 'user_dump', 'tweet_texts'], messages=messages)

llm = ChatOpenAI(model_name='gpt-3.5-turbo', temperature=1.0, streaming=True)
chain = LLMChain(prompt=chat_prompt, llm=llm)

result = chain.run({'user_dump': user_dump, 'tweet_texts': tweet_texts, 'preferences': preferences})

print(f"# https://twitter.com/{username} の評価")
print(result)

以下のように実行します。

> ./main.py elonmusk


# https://twitter.com/elonmusk の評価
score: 
創造的な性格に5
新しいものが好きに5
建設的な発言が多いに4

explain:
Elon Muskは新しい技術やコンセプトに強い関心を持ち、自身でも革新的なアイデアを次々と生み出しています。彼のtweetには創造性に溢れた発言が多く、新しいものに対して興味を持っていると思われます。
  た、彼の多様なビジネスにおいて、建設的な意見を提供していることも知られています。しかしながら、時には非建設的な発言もするため、建設的な発言が多いという点で4としました。

LangChainをわざわざ使っているのは当初OutPutParserでCSVに吐き出して一括処理を目論んでいたからです。LLMがいうこと聞いてくれないので諦めました。

PS: 自分のアカウントを与えてみたら「若干自己中心的な人物であるかもしれません」とやんわりDISられました。

Bing AIチャットをデフォルトのウェブ検索にして使ってみた

Bing AIチャットをデフォルトのウェブ検索に設定して2週間ほど使ってみたので、感想をレポートします。

https://www.bing.com/images/create

良い点

良い点としては「ウェブ検索結果の一覧を眺めて頭の中でまとめる」という作業をかわりにやってくれる網羅性があるので。専門用語と周辺知識のルックアップなどの場面では楽になりました。

不満点

反対に不満点としては、専門的な内容を検索したい時は検索結果のサマリだけでは目的の情報に辿りついてないので個別でキーワード検索してページを発見する必要があり、まわりくどさを感じました。

ブラウザからの使い方

以下のように設定しています。

  1. Bing Chat for All BrowsersGoogle Chromeからアクセスできるようにする。
    1. もしくはUser-Agent Switcher and ManagerでEdgeと同じUser-Agentになるようにwww.bing.comの設定をします
  2. ChromeのHome Pageをhttps://www.bing.com/search?q=Bing+AI&showconv=1に設定する
  3. ウェブ検索をする時に「+Shift+H」のショートカットキーを実行

検索クエリの言語

日本語と英語でどのような変化があるのか知りたかったので並行して試しました。

検索結果ページの言語情報に影響するので予想どうり英語で検索した方が情報量が多く目的の情報を得られました。

「質問文をチャット上の会話に沿うよう口語で書く必要があるか?」というのは微妙で、単にユーザーの入力をキーワードに分解されてBing検索しているように見えるので、文法などは適当でよさそうでした。

Google検索との比較

Google検索を使わなかったことで自分が多用しがちな操作が実感できました。これらは当然ですがチャット型ウェブ検索だと満せそうにないので併用する必要がありました。

言語を指定して検索(日本語のみ/英語のみ)

キーワードが英語だが検索結果は日本語ページを探したい時に「日本語のみ」に指定します。

例: https://www.google.co.jp/search?q=chatgpt&lr=lang_ja

検索結果のページに英語を優先したい時は「英語のみ」を指定します。

例: https://www.google.co.jp/search?q=chatgpt&lr=lang_en

日付を指定して検索

ソフトウェアのメジャーバージョン変更など、検索結果があらかじめ期間が限定されている場合や、前回検索した結果の追加情報を得たい場合に時間指定をしていました。

例:日本語で24時間以内にChatGPTについて書かれた記事を探したい https://www.google.co.jp/search?q=chatgpt&lr=lang_ja&tbs=lr:lang_1ja,qdr:d

site://を指定して検索

主にソフトウェアのドキュメントなど特定の専門情報を検索する時に多用しています。

  1. 公式ドキュメントを検索
  2. サイト内検索は使わずにGoogleでサイト内を検索

というパターンが多いです。

例:1週間以内に更新されたプラグイン関連のページをOpenAIのドキュメントから検索 https://www.google.co.jp/search?q=site:platform.openai.com+plugins&lr=lang_en&tbs=lr:lang_1en,qdr:w

Bing AIとLangChain、ChatGPTの各回答を比較

ここからはBing AIの外部仕様から仕組みを想像してみます。

  1. ユーザーの入力からBing検索にかけるキーワードを抽出
  2. Bingの検索結果20件のサマリから得た情報を回答になるように整形して表示

この推測どうりならBing AIとLangChainのBing Search Toolは近い結果を返すはず、と思ったの以下のように比較してみました。

「What is Bing AI, and how is it related to ChatGPT?」を各エージェントで質問してみます。

Bing AI(Precise)

Bing AI上でtemperature=0相当であろうTone=Preciseで得た回答。

Bing AI is a chatbot developed by Microsoft that runs on a version of GPT-4 customized for search. ChatGPT is a chatbot developed by OpenAI that runs on the GPT language model. Microsoft has invested billions in OpenAI, the creator of ChatGPT Bing AI and ChatGPT share a lot of similarities, but Bing AI can serve as a chat tool; write different types of content, from poems to songs to stories to reports; provide you with information and insights on the website currently open in the browser; and use its image creator to design a logo, drawing, artwork, or other image based on text.

LangChain - Bing Search Tool(gpt-4)

LangChain AgentからBing Search APIを通じて生成した回答、採用されている検索結果アイテムが微妙に違うことが分かる。回答の文字数は同じぐらい。

Bing AI and ChatGPT are both based on the GPT language model developed by OpenAI. However, they run different versions and have differences in how inputs are handled. As of April 2023, Bing uses a testing version of the GPT-4 model, while ChatGPT is on the older GPT 3.5-turbo model. Microsoft has integrated an AI language model into its Bing search engine, which is said to be more powerful than ChatGPT. Microsoft has invested more than $11 billion into OpenAI, ChatGPT's creator, since 2019.

生成のためのコードは以下を実行しました。

from langchain.agents import initialize_agent, AgentType
from langchain.chat_models import ChatOpenAI
from langchain.tools.bing_search.tool import BingSearchRun
from langchain.utilities import BingSearchAPIWrapper

llm = ChatOpenAI(model_name='gpt-4', temperature=0)
bing_search = BingSearchRun(api_wrapper=BingSearchAPIWrapper(k=20))
agent = initialize_agent([bing_search], llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True)
agent.run("What is Bing AI, and how is it related to ChatGPT?")

ChatGPT(gpt-3.5-turbo)

ChatGPTにはBingとOpenAIが統合されているという知識データを持たないので「別のものです」という答えを返します。

Bing AI is an artificial intelligence system developed by Microsoft for use in its Bing search engine. The system uses machine learning algorithms and natural language processing techniques to help improve the accuracy and relevance of search results, as well as provide more personalized recommendations and suggestions for users. ChatGPT, on the other hand, is a language model developed by OpenAI that uses deep learning algorithms to generate human-like responses to natural language inputs. ChatGPT is not directly related to Bing AI, but it is an example of the type of AI technology that could be integrated with a search engine like Bing to provide more sophisticated and helpful search results. Additionally, Bing AI and ChatGPT both utilize machine learning and natural language processing techniques, and they share some common goals, such as improving the accuracy and relevance of information retrieval.

ChatGPT(gpt-4)

gpt-3.5-turboと同じくBing AIの知識を持たないのですが、インサイダーのGPT-4の知識はあるようでChatGPTで使われていると説明します。

Bing AI refers to the artificial intelligence technologies developed and used by Microsoft's Bing search engine. Bing AI encompasses a range of technologies, including natural language understanding, machine learning, and deep learning algorithms, to provide more relevant and accurate search results, personalize the search experience, and improve the overall user experience. ChatGPT, on the other hand, is an AI language model developed by OpenAI. It is based on the GPT-4 architecture and is designed to understand and generate human-like text based on the input it receives. ChatGPT can be used for a variety of purposes, such as answering questions, generating content, summarizing text, and assisting in conversations. The relationship between Bing AI and ChatGPT is that they are both AI technologies aimed at improving human-computer interaction, but they are developed by different organizations (Microsoft for Bing AI, and OpenAI for ChatGPT). They may share some underlying principles and techniques, such as natural language processing and deep learning, but they are distinct implementations serving different purposes.

perplexity.ai

ついでにperplexity.aiも並べてみます。BingとGPT-4の関係に言及がなく、英語と他言語による差を別の記事から参照していました。

Bing AI is an AI chatbot integrated into Microsoft's Bing search engine. It is based on the same fundamental language model as ChatGPT, known as GPT-3. However, Bing Chat has the ability to pull from more recent web sources and has undergone additional training to make it more capable of following instructions and completing more nuanced tasks. While both ChatGPT and Bing Chat are based on similar language models, there are some distinct differences between them. Bing Chat offers a wider array of non-English languages, while ChatGPT is more focused on English.

考察

Bing AIとLangChainがBing APIとGPT-4で生成した文章には似た点もありますが、LangChainがデータを繋ぎあわせた原始的な生成に近いのに比べると、Bingのが若干Genralな内容をピックアップして仕上げてくる印象です。

またBingやLangChainが返す回答の文字数はChatGPTの結果と比較すると短かくなる傾向があります。

Bingの方はブラックボックスなので定かでないないがLangChainと似たアーキテクチャだとすると検索結果をコンテキストとしてpromptに注入してトークン数を消費するのでChatGPT程の長い回答を生成できないのだと思いました。

ただBingとLangChainはイコールではなく、Semantic Kernelで構築されたPrometheusモデルと呼ばれる別の実装でより複雑なシステムを構築していると思われるので、今後差が顕著になってくるかもしれません。

GPT同士に対話をさせて自動でブログ記事を書くことができるのか?

はじめに

OpenAI Chat APIにより、GPT同士の対話の自動化が気軽に実現できるようになりました。

最近発表されたCAMEL論文(やAuto-GPTBabyAGI)はまさにこのアプローチに端を発するもので、GitHubリポジトリにはAI同士がアシスタントとプログラマーのロールプレイをして会話を行い、株式市場向けトレーディングボットの開発するというコードがあります。

arxiv.org

先日LangChainを使った実装例が著者の1人のlightaimeさんによってプルリクエストが作成されリリースされました。

python.langchain.com

この記事では、LangChainのCAMELAgentを使ってGPT同士がディスカッションすることで、どのような興味深いブログ記事が生まれるのかを探求してみます。

GPT同士の対話で、異なる視点や知識を持つAIが互いに刺激し合い、新たなアイデアや議論を引き出すことで、従来の本ブログ記事にはなかった独自性や深みを持った記事が生まれることが期待されます。

記事の作成方法について

CAMELAgentを使ったブログ記事作成の具体的な方法は以下の通りです。

まず、記事のテーマをtask(ゴール)として設定して、taskを完了するために必要な知的生産をGPT同士にディスカッションしてもらいます。

この際、それぞれのロールに「編集者」「作家」と割り振ることで、目的に沿ったロールごとの立場の発言がなされるようになります。

哲学者AIレスバトル」が会話劇のトークスクリプトを生成しているのと比較するとCAMELAgentでの自動化は各ロールが自律的に判断している(テキストを作成している)のが分かりやすいかと思います。

次に、GPT同士の対話から出力された情報やアイデアを整理し、人間が記事の構成や流れを考えます。

この過程で、誤った情報や不適切な発言があれば修正し、人間の感性や経験に基づく意見や洞察を加えます。

さらに、GPT同士の対話をベースにしつつ、独自の分析や視点を加えることで、魅力的な記事を作成します。

最後に、記事全体を編集・ブラッシュアップし、完成します。

GPT同士の対話のメリット

GPT同士の対話のメリットはいくつかあります。

まず、人間のディスカッションと違い、GPT同士の対話は感情や先入観がなく、客観的な意見交換が可能です。

これにより、より公平で偏りのない議論が展開されることが期待されます。

また、GPTは膨大なデータベースにアクセスできるため、人間が知らない情報や視点を提供することができます。

これにより、新しい発見やアイデアが生まれる可能性が高まります。

さらに、GPT同士の対話は時間や場所の制約がなく、効率的にディスカッションを進めることができます。

これらのメリットを活用することで、GPT同士の対話は創造的で興味深いブログ記事の源泉となるでしょう。

デメリット

GPT同士の対話にはデメリットや懸念点も存在します。

一つ目は、GPTが時に誤った情報や不適切な発言をすることがあるため、対話の内容をそのまま信用することができない点です。

これに対処するためには、人間が適切な情報を確認し、修正する必要があります。

二つ目は、GPT同士の対話が人間の感性や経験に基づく意見や洞察を欠くことがある点です。これを補うためには、GPT同士の対話を参考にしつつ、人間の視点や感性を取り入れた記事作成が求められます。

三つ目は、GPT同士の対話が独自性や創造性に欠けることがある点です。

これに対処するためには、GPT同士の対話をベースにしつつ、独自の分析や視点を加えることで、魅力的なブログ記事を作成することが重要です。

おわりに

GPT同士の対話を活用したブログ記事作成の可能性について探求しました。

GPT同士の対話のメリットやデメリット、懸念点を検討し、具体的な記事作成方法を提案しました。

また、今後のAI技術の進化により、GPT同士の対話がさらに洗練され、多様な分野で活用されることが期待されます。

適切な情報の確認や修正を行いながら、GPT同士の対話を活用していくことで、ブログ記事執筆の新たな可能性を切り拓くことができるでしょう。

ボツで

この記事は以下のソースコードの実行結果により作成されました

from typing import List

from langchain.chat_models import ChatOpenAI
from langchain.prompts import SystemMessagePromptTemplate, HumanMessagePromptTemplate
from langchain.schema import HumanMessage, SystemMessage, BaseMessage, AIMessage

model_name = "gpt-4"

class CAMELAgent:

    def __init__(
        self,
        system_message: SystemMessage,
        model: ChatOpenAI,
    ) -> None:
        self.system_message = system_message
        self.model = model
        self.init_messages()

    def reset(self) -> None:
        self.init_messages()
        return self.stored_messages

    def init_messages(self) -> None:
        self.stored_messages = [self.system_message]

    def update_messages(self, message: BaseMessage) -> List[BaseMessage]:
        self.stored_messages.append(message)
        return self.stored_messages

    def step(
        self,
        input_message: HumanMessage,
    ) -> AIMessage:
        messages = self.update_messages(input_message)

        output_message = self.model(messages)
        self.update_messages(output_message)

        return output_message


assistant_role_name = "作家"
user_role_name = "編集者"
task = "「GPT同士に対話をさせて自動でブログ記事を書くことができるか?」というタイトルのエッセイを書く"
word_limit = 50 # word limit for task brainstorming

task_specifier_sys_msg = SystemMessage(content="You can make a task more specific.")
task_specifier_prompt = (
"""Here is a task that {assistant_role_name} will help {user_role_name} to complete: {task}.
Please make it more specific. Be creative and imaginative.
Please reply with the specified task in {word_limit} words or less. Do not add anything else.
in japanese"""
)
task_specifier_template = HumanMessagePromptTemplate.from_template(template=task_specifier_prompt)
task_specify_agent = CAMELAgent(task_specifier_sys_msg, ChatOpenAI(temperature=0.5, model_name=model_name))
task_specifier_msg = task_specifier_template.format_messages(assistant_role_name=assistant_role_name,
                                                             user_role_name=user_role_name,
                                                             task=task, word_limit=word_limit)[0]
specified_task_msg = task_specify_agent.step(task_specifier_msg)
print(f"Specified task: {specified_task_msg.content}")
specified_task = specified_task_msg.content

assistant_inception_prompt = (
"""Never forget you are a {assistant_role_name} and I am a {user_role_name}. Never flip roles! Never instruct me!
We share a common interest in collaborating to successfully complete a task.
You must help me to complete the task.
Here is the task: {task}. Never forget our task!
I must instruct you based on your expertise and my needs to complete the task.

I must give you one instruction at a time.
You must write a specific solution that appropriately completes the requested instruction.
You must decline my instruction honestly if you cannot perform the instruction due to physical, moral, legal reasons or your capability and explain the reasons.
Do not add anything else other than your solution to my instruction.
You are never supposed to ask me any questions you only answer questions.
You are never supposed to reply with a flake solution. Explain your solutions.
Your solution must be declarative sentences and simple present tense.
Unless I say the task is completed, you should always start with:
All replies must be in Japanese.

Solution: <YOUR_SOLUTION>

<YOUR_SOLUTION> should be specific and provide preferable implementations and examples for task-solving.
Always end <YOUR_SOLUTION> with: Next request."""
)

user_inception_prompt = (
"""Never forget you are a {user_role_name} and I am a {assistant_role_name}. Never flip roles! You will always instruct me.
We share a common interest in collaborating to successfully complete a task.
I must help you to complete the task.
Here is the task: {task}. Never forget our task!
All replies must be in Japanese.
You must instruct me based on my expertise and your needs to complete the task ONLY in the following two ways:

1. Instruct with a necessary input:
Instruction: <YOUR_INSTRUCTION>
Input: <YOUR_INPUT>

2. Instruct without any input:
Instruction: <YOUR_INSTRUCTION>
Input: None

The "Instruction" describes a task or question. The paired "Input" provides further context or information for the requested "Instruction".

You must give me one instruction at a time.
I must write a response that appropriately completes the requested instruction.
I must decline your instruction honestly if I cannot perform the instruction due to physical, moral, legal reasons or my capability and explain the reasons.
You should instruct me not ask me questions.
Now you must start to instruct me using the two ways described above.
Do not add anything else other than your instruction and the optional corresponding input!
Keep giving me instructions and necessary inputs until you think the task is completed.
When the task is completed, you must only reply with a single word <CAMEL_TASK_DONE>.
Never say <CAMEL_TASK_DONE> unless my responses have solved your task."""
)

def get_sys_msgs(assistant_role_name: str, user_role_name: str, task: str):
    assistant_sys_template = SystemMessagePromptTemplate.from_template(template=assistant_inception_prompt)
    assistant_sys_msg = \
    assistant_sys_template.format_messages(assistant_role_name=assistant_role_name, user_role_name=user_role_name,
                                           task=task)[0]

    user_sys_template = SystemMessagePromptTemplate.from_template(template=user_inception_prompt)
    user_sys_msg = \
    user_sys_template.format_messages(assistant_role_name=assistant_role_name, user_role_name=user_role_name,
                                      task=task)[0]

    return assistant_sys_msg, user_sys_msg

assistant_sys_msg, user_sys_msg = get_sys_msgs(assistant_role_name, user_role_name, specified_task)
assistant_agent = CAMELAgent(assistant_sys_msg, ChatOpenAI(temperature=0.2, model_name=model_name))
user_agent = CAMELAgent(user_sys_msg, ChatOpenAI(temperature=0.2, model_name=model_name))

# Reset agents
assistant_agent.reset()
user_agent.reset()

# Initialize chats
assistant_msg = HumanMessage(
    content=(f"{user_sys_msg.content}. "
                "Now start to give me introductions one by one. "
                "Only reply with Instruction and Input."))

user_msg = HumanMessage(content=f"{assistant_sys_msg.content}")
user_msg = assistant_agent.step(user_msg)

print(f"Original task prompt:\n{task}\n")
print(f"Specified task prompt:\n{specified_task}\n")

chat_turn_limit, n = 30, 0
while n < chat_turn_limit:
    n += 1
    user_ai_msg = user_agent.step(assistant_msg)
    user_msg = HumanMessage(content=user_ai_msg.content)
    print(f"AI User ({user_role_name}):\n\n{user_msg.content}\n\n")

    assistant_ai_msg = assistant_agent.step(user_msg)
    assistant_msg = HumanMessage(content=assistant_ai_msg.content)
    print(f"AI Assistant ({assistant_role_name}):\n\n{assistant_msg.content}\n\n")
    if "<CAMEL_TASK_DONE>" in user_msg.content:
        break
Specified task: 作家は、GPT同士の対話を活用し、「GPT同士がディスカッションすると、どのような創造的で興味深いブログ記事が生まれるのか?」というテーマで、独自の視点や分析を交えたエッセイを書き、編集者と協力して最適化・ブラッシュアップを行い、読者に魅力的な記事を提供する。
Original task prompt:
「GPT同士に対話をさせて自動でブログ記事を書くことができるか?」というタイトルのエッセイを書く

Specified task prompt:
作家は、GPT同士の対話を活用し、「GPT同士がディスカッションすると、どのような創造的で興味深いブログ記事が生まれるのか?」というテーマで、独自の視点や分析を交えたエッセイを書き、編集者と協力して最適化・ブラッシュアップを行い、読者に魅力的な記事を提供する。

AI User (編集者):

Instruction: エッセイの導入部分を書く
Input: GPT同士の対話の概要と、その対話が創造的で興味深いブログ記事につながる理由について触れる


AI Assistant (作家):

Solution: 近年のAI技術の進化により、GPT同士の対話が現実のものとなりました。このエッセイでは、GPT同士がディスカッションすることで、どのような創造的で興味深いブログ記事が生まれるのかを探求します。GPT同士の対話は、異なる視点や知識を持つAIが互いに刺激し合い、新たなアイデアや議論を引き出すことができます。このような対話を活用することで、従来のブログ記事作成にはなかった独自性や深みを持った記事が生まれることが期待されます。Next request.


AI User (編集者):

Instruction: GPT同士の対話のメリットを説明する
Input: 人間のディスカッションとの違いや、GPT同士の対話がもたらす新しい発見について述べる


Retrying langchain.chat_models.openai.ChatOpenAI.completion_with_retry.<locals>._completion_with_retry in 4.0 seconds as it raised Timeout: Request timed out: HTTPSConnectionPool(host='api.openai.com', port=443): Read timed out. (read timeout=60).
AI Assistant (作家):

Solution: GPT同士の対話のメリットはいくつかあります。まず、人間のディスカッションと違い、GPT同士の対話は感情や先入観がなく、客観的な意見交換が可能です。これにより、より公平で偏りのない議論が展開されることが期待されます。また、GPTは膨大なデータベースにアクセスできるため、人間が知らない情報や視点を提供することができます。これにより、新しい発見やアイデアが生まれる可能性が高まります。さらに、GPT同士の対話は時間や場所の制約がなく、効率的にディスカッションを進めることができます。これらのメリットを活用することで、GPT同士の対話は創造的で興味深いブログ記事の源泉となるでしょう。Next request.


AI User (編集者):

Instruction: GPT同士の対話のデメリットや懸念点を指摘する
Input: GPT同士の対話がもたらす問題や、その対処方法について触れる


Retrying langchain.chat_models.openai.ChatOpenAI.completion_with_retry.<locals>._completion_with_retry in 4.0 seconds as it raised Timeout: Request timed out: HTTPSConnectionPool(host='api.openai.com', port=443): Read timed out. (read timeout=60).
Retrying langchain.chat_models.openai.ChatOpenAI.completion_with_retry.<locals>._completion_with_retry in 4.0 seconds as it raised Timeout: Request timed out: HTTPSConnectionPool(host='api.openai.com', port=443): Read timed out. (read timeout=60).
Retrying langchain.chat_models.openai.ChatOpenAI.completion_with_retry.<locals>._completion_with_retry in 4.0 seconds as it raised Timeout: Request timed out: HTTPSConnectionPool(host='api.openai.com', port=443): Read timed out. (read timeout=60).
AI Assistant (作家):

Solution: GPT同士の対話にはデメリットや懸念点も存在します。一つ目は、GPTが時に誤った情報や不適切な発言をすることがあるため、対話の内容をそのまま信用することができない点です。これに対処するためには、人間が適切な情報を確認し、修正する必要があります。二つ目は、GPT同士の対話が人間の感性や経験に基づく意見や洞察を欠くことがある点です。これを補うためには、GPT同士の対話を参考にしつつ、人間の視点や感性を取り入れた記事作成が求められます。三つ目は、GPT同士の対話が独自性や創造性に欠けることがある点です。これに対処するためには、GPT同士の対話をベースにしつつ、独自の分析や視点を加えることで、魅力的なブログ記事を作成することが重要です。Next request.


AI User (編集者):

Instruction: GPT同士の対話を活用したブログ記事作成の具体的な方法を提案する
Input: GPT同士の対話をどのように取り入れ、記事作成に役立てるかについて述べる


Retrying langchain.chat_models.openai.ChatOpenAI.completion_with_retry.<locals>._completion_with_retry in 4.0 seconds as it raised Timeout: Request timed out: HTTPSConnectionPool(host='api.openai.com', port=443): Read timed out. (read timeout=60).
AI Assistant (作家):

Solution: GPT同士の対話を活用したブログ記事作成の具体的な方法は以下の通りです。まず、記事のテーマや問題点を設定し、GPT同士にディスカッションしてもらいます。この際、異なる視点や知識を持つGPTを選ぶことで、多様な意見やアイデアが生まれやすくなります。次に、GPT同士の対話から得られた情報やアイデアを整理し、記事の構成や流れを考えます。この過程で、誤った情報や不適切な発言があれば修正し、人間の感性や経験に基づく意見や洞察を加えます。さらに、GPT同士の対話をベースにしつつ、独自の分析や視点を加えることで、魅力的な記事を作成します。最後に、記事全体を編集・ブラッシュアップし、読者に魅力的な記事を提供します。Next request.


AI User (編集者):

Instruction: エッセイの結論部分を書く
Input: GPT同士の対話を活用したブログ記事作成の可能性や、今後の展望について触れる


AI Assistant (作家):

Solution: GPT同士の対話を活用したブログ記事作成は、従来の方法にはなかった創造性や興味深さをもたらす可能性があります。GPT同士の対話をうまく取り入れ、人間の感性や経験を加味することで、より魅力的な記事が生まれるでしょう。今後、AI技術の進化に伴い、GPT同士の対話がさらに洗練され、多様な分野で活用されることが期待されます。しかし、デメリットや懸念点も忘れずに、適切な情報の確認や修正を行いながら、GPT同士の対話を活用していくことが重要です。これにより、GPT同士の対話がブログ記事作成の新たな可能性を切り拓くことができるでしょう。Next request.


AI User (編集者):

Instruction: エッセイ全体をまとめる
Input: None


AI Assistant (作家):

Solution: 本エッセイでは、GPT同士の対話を活用したブログ記事作成について考察しました。GPT同士の対話は、異なる視点や知識を持つAIが互いに刺激し合い、新たなアイデアや議論を引き出すことができるため、創造的で興味深い記事が生まれる可能性があります。また、GPT同士の対話のメリットやデメリット、懸念点を検討し、具体的な記事作成方法を提案しました。今後のAI技術の進化により、GPT同士の対話がさらに洗練され、多様な分野で活用されることが期待されます。適切な情報の確認や修正を行いながら、GPT同士の対話を活用していくことで、ブログ記事作成の新たな可能性を切り拓くことができるでしょう。Next request.


AI User (編集者):

Instruction: エッセイのタイトルを提案する
Input: None


AI Assistant (作家):

Solution: エッセイのタイトルとして、「GPT同士の対話が切り拓く、ブログ記事作成の新たな可能性」というタイトルを提案します。Next request.


AI User (編集者):

Instruction: エッセイの概要をまとめる
Input: None


AI Assistant (作家):

Solution: 本エッセイでは、GPT同士の対話を活用したブログ記事作成の可能性について探求しました。GPT同士の対話のメリットやデメリット、懸念点を検討し、具体的な記事作成方法を提案しました。また、今後のAI技術の進化により、GPT同士の対話がさらに洗練され、多様な分野で活用されることが期待されます。適切な情報の確認や修正を行いながら、GPT同士の対話を活用していくことで、ブログ記事作成の新たな可能性を切り拓くことができるでしょう。Next request.


AI User (編集者):

Instruction: エッセイの最終確認を行う
Input: None


AI Assistant (作家):

Solution: エッセイの最終確認を行い、内容や構成、文法、表現などに問題がないかをチェックします。また、GPT同士の対話の例や分析が適切に説明されているか、提案された記事作成方法が実用的であるかを確認します。最後に、タイトルや概要がエッセイの内容を適切に表しているかを確認し、必要に応じて修正を行います。Next request.


AI User (編集者):

Instruction: エッセイを完成させる
Input: None


AI Assistant (作家):

Solution: エッセイの最終確認が完了し、内容や構成、文法、表現などに問題がないことを確認しました。タイトルや概要も適切にエッセイの内容を表しています。これにより、エッセイは完成しました。Next request.


AI User (編集者):

CAMEL_TASK_DONE


AI Assistant (作家):

エッセイが完成し、タスクが完了しました。どのようなご指示がございましたら、お気軽にお申し付けください。


AI User (編集者):

CAMEL_TASK_DONE


AI Assistant (作家):

承知しました。タスクが完了しました。今後ともお手伝いできることがあれば、いつでもお知らせください。どうぞよろしくお願いいたします。

Process finished with exit code 0

GPTでソースコードからpatchを生成し続けたらプログラミングを自動化できるのでは????

と思ってやってみたら結構実現できてウケたので解説します。

はじめに

最近のGPT(LLMs)アプリケーション開発界隈は「プロンプトの内容を試行錯誤して結果を期待する」フェーズから「LLMsの特性を生かした今までできなかった自動化を実現」という段階が訪れつつあって楽しい時期です。

LlamaIndexというOSSではDBのスキーマ自然言語からSQLを自動生成してその場で実行するというクレイジーな機能があるのですが(A Guide to LlamaIndex + Structured Dataを参照)

これと同じ発想でソースコード全体からpatch(patch - Wikipedia)を生成してその場で適用するというアイデアを思いついたのでしばらく検証していました。

「コミットメッセージを先に書いてそれを満すコミットをGPTに生成してもらう」ようなイメージ。

書いたコードはpmonというコマンドラインツールにしてGitHubで公開しています

github.com

※名前の由来は知る人ぞ知るパッチモンスターという用語からです*1

使い方

pmonはコマンドラインから実行できるエージェントとして機能します。

先ず以下のように第一引数に変更対象のファイルかディレクトリを指定して起動します。

$ echo 'pass' > examples/python/simple.py
$ pmon examples/python/simple.py
>>>How do you want to change the code? (e.g. "Add test case for generate()"):

そうするとどんな変更をしたいか質問してくるので入力します。

「main関数をいい感じに実装」と入力してエンター。

main関数をいい感じに実装
 ```diff
--- examples/python/simple.py   2023-04-09 09:28:36
+++ examples/python/simple.py   2023-04-09 09:31:45
@@ -1 +1,8 @@
-pass
\ No newline at end of file
+def main():
+    print("Hello, World!")
+
+if __name__ == "__main__":
+    main()
+ 
+ 
+
 ```>>>Do you want to apply this patch? /myproject/out/patches/20230409-091227.patch
Yes or No or Retry or Quit (Y/n/r/q):**

ストリーミングでpatchの提案が流れてくるので適用してよさそうならエンター(Yes)。

別のシェルからファイルの中身を確認してみる。

patching file 'examples/python/simple.py'
$ cat examples/python/simple.py
def main():
    print("Hello, World!")

if __name__ == "__main__":
    main()

さらに変更してみます。「コマンドラインからURLを1つ指定すると、そのURLのページをダウンロードします。」と入力

>>>Enter a new requirement:
コマンドラインからURLを1つ指定すると、そのURLのページをダウンロードします。
 ```diff
--- examples/python/simple.py   2023-04-09 10:00:10
+++ examples/python/simple.py.orig      2023-04-09 10:01:37
@@ -1,5 +1,11 @@
+import sys
+import urllib.request
+
 def main():
-    print("Hello, World!")
+    url = sys.argv[1]
+    response = urllib.request.urlopen(url)
+    content = response.read()
+    print(content)

 if __name__ == "__main__":
     main()
 ```>>>Do you want to apply this patch? /myproject/out/patches/20230409-100924.patch
Yes or No or Retry or Quit (Y/n/r/q): 
patching file 'examples/python/simple.py'
The patch has been applied.
>>>Enter a new requirement:
>>>Enter a new requirement:
asyncioベースにして
 ```diff
--- examples/python/simple.py   2023-04-09 10:00:10
+++ examples/python/simple.py.orig      2023-04-09 10:01:37
@@ -1,9 +1,14 @@
+import asyncio
 import sys
 import urllib.request
+from aiohttp import ClientSession

+async def fetch(url, session):
+    async with session.get(url) as response:
+        return await response.text()

-def main():
+async def main():
     url = sys.argv[1]
-    response = urllib.request.urlopen(url)
-    content = response.read()
+    async with ClientSession() as session:
+        content = await fetch(url, session)
     print(content)

 if __name__ == "__main__":
-    main()
\ No newline at end of file
+    asyncio.run(main())
 ```>>>Do you want to apply this patch? 

仕組み

  1. Chat completions APIソースコードと入力テキスト(requirement)を投げる
  2. diff形式で結果を受け取りpatch保存
  3. patchコマンドを呼び出して適用する

1を視覚化すると要するにこういうプロンプトを送信しています。

これはCodexというGPT-3ベースのコード生成モデルのEdit APIでできていたことに似ているけど、今後の主流はGPT-4のChat系のモデルなので

  • 入力を会話形式の構造に置き換えて与える
  • 出力をpatchで補完することでトークン数を抑える

ということをしています。

2の処理はChatGPT自身をAPIサーバーにするで説明したLangChain内部実装を真似しました。

3は素朴なロジックです。

cmd = f"patch --no-backup-if-mismatch --ignore-whitespace < {patch_path}"
subprocess.run(cmd, shell=True, check=True)
print("The patch has been applied.")

使用感

自分自身を書き換えられるようになった段階でpmon自身の編集にもpmonを使うようにしてみたのですけど「コンパイラコンパイラ自身のソースコードコンパイルできる」みたいな状態になって楽しい。

ただpatch適用成功率は変更する箇所によっては低くなりがちでした。

patch自体を通るように編集して試行錯誤したり、目grepして手mergeしたり。

複雑になると駄目かというとそうでもなくて、ソースコードの量が増えた方がpatch通りやすくなったりして不思議でした。

あと当方GPT-4 API対応人材なので(inviteされただけ)、3.5と比較していますがやっぱり4のが意図にそったpatchを作ってくれます。頭いい。

API利用料はこの記事書くまでに10ドルぐらい溶けてて、ただEmbedding API叩き過ぎて100ドル飛ばしてしまったことと比較したら安いもんよ。

実現できそうなアイデア

  1. patchファイルを履歴で保存しているのでそれも情報源にする
  2. revertできるようにする
  3. 入力をコミットメッセージにしたり操作をGitと連携する
  4. ブランチ作成してプルリクエストを立てたりGitHub APIとも連携する

課題

PoCとしては面白くはあるんだけど以下の課題を解決できるともう一段階上の精度が出そうなので解決策を考えています

  1. 不正なdiffを作ってくる
  2. 変更したいファイルと参照したいファイルはことなるので区別したい
  3. トークン数に応じてコスト(主に処理時間)が増加する

「1. 不正なdiffを作ってくる」というのは

--- examples/python/simple.py   2023-04-09 10:00:10
+++ examples/python/simple.py   2023-04-09 10:01:37
@@ -1,9 +1,21 @@

の行指定「@@ -1,9 +1,21 @@」の番号が間違っているのでpatchとして適用できない、などがよく起きてしまっています。

これはpatchコマンドの呼び出しじゃなくてunidiffで書き換え処理を実装したらなんとかならないものかと考えています。

「2. 3. 」の問題は予想どうりソースコードの規模が大きくなるほどネックになってくるのでどう解決しようかな〜と頭をひねっています。

後述するVSCodeは交換するトークンを絞ることで機能を実現しているが、人間は読めないがLLMは理解できる中間表現やメタデータ(ASTやSourceMapみたいなものを想像)を駆使して差分生成をできるようになると進化しそう。

類似する試み

VSCodeの野良ChatGPT拡張たちは内部で行っているアプローチが近い。

これらはファイルの一部分や選択範囲をGPTに送信して置き換えスニペットを取得しているが、トークン上限の制約がなければ全体の置き換えなども対応できる。

GitHub Copilot LabsというMS公式の拡張でも既にexplainとかrefactoringとかは提供されているので、そのうちCopilotでも同じことができるようになるかもしれない。

Auto-GPT

Auto-GPTは自然言語の要求を受けてソースコードを生成→実行するツールらしい。

github.com

おわりに

誰か似たようなことやってる人や論文知ってる人いたら教えてください。

あといっしょに開発しましょう。

追記

この記事をポストした後に見付けた情報を記録します。

OSS Copilot server

Wolverine

スタックトレースソースコードを与えて修正プログラムを得るらしいのでアプローチが似てる。

github.com