2024.04.08
LLMコード生成ツール:plandexを試してみた
みなさんこんにちは、グループ研究開発本部 AI研究開発室のK.Fです。
最近、大規模言語モデル(LLM)を活用したコード生成ツールが注目を集めていますよね。先月(2024年3月)には、Devin AIがCognitionから発表され話題を集めていました。まだ、waiting list状態ですが、実際に試せる日が待ち遠しいです。今回は、そのDevin AIに影響され積極的に開発が進んでいるOSSのコード生成ツールを試してみます。
トレンド調査
GitHub Trendingを眺めていると、以下のようなものが注目を集めているようです。
- Devika: https://github.com/stitionai/devika
- OpenDevin: https://github.com/OpenDevin/OpenDevin
- gpt-pilot: https://github.com/Pythagora-io/gpt-pilot
- plandex: https://github.com/plandex-ai/plandex
OpenDevinとDevikaは、devinをそのままOSSで実現しようとしているものです。どちらも実行すると、localhostにweb guiが立ち上がり、チャットベースで問い合わせを行いながら開発を進めていく形になります。Shellとcode editorとbrowserがweb guiに表示され、chatに入力した内容に応じてLLMが自動で環境の構築からファイルの編集まで自動で進めてくれます。OpenDevinを少し試してみたところ、OpenInterpreterに近いと感じ、試したみたことのある人はわかると思うのですが、一度ハマってしまうと迷走してしまってうまくいかないことが多そうです。
gpt-pilotはVSCodeの拡張機能として提供されているみたいで、一番簡単に試すことができます。Specification Writer、Architect、Tech Lead、Developer、Code Monkey、Reviewerなどのエージェントを複数用意して、お互いに協力しながら開発を進めてくれます。あくまでに人間はレビュー者として存在しており、各エージェントが提案してきたタスクを行ってよいかの承認をするイメージで進みます。少し試したみたところ、簡単なweb appの作成をお願いしたのに、user認証機能を用意して、ログイン画面を作ろうとするなどかなり暴走気味に開発が進みました。どこかからテンプレートを持ってきて参考にする機能がついているのか、成果物の完成度は高いですが、求めている仕様を満たす最低限の機能だけではなく余計なことをしてしまうイメージでした。
最後に、plandexです。こちらは基本的に開発者の生産性向上を目的とされており、cliベースで提供されています。少し触ってみて、上で紹介したものの中だと一番実用的だと感じたので、実際に検証した内容を紹介していきます。
検証
plandexを検証していきます。取り組んでもらうタスクは「markdownをhtmlに変換してくれるweb appを作る」にします。基本的に、plandex tellで指示を与えると、その指示を達成するための計画(plan)と、subtasksを書き出してくれます。実際に、plandexが出力したplanとsubtasksは以下のとおりです。
To build a web application that converts Markdown to HTML, we'll use a simple and popular stack: Node.js for the backend, Express.js as the web server framework, and a third-party library to parse Markdown. For the frontend, we'll keep it simple with HTML and vanilla JavaScript to send the Markdown content to the backend and display the converted HTML. ### Plan Overview: 1. Set up the project structure: Create the necessary directories and files. 2. Initialize a Node.js project: Use npm to initialize the project and manage dependencies. 3. Install necessary packages: Install Express.js and a Markdown parsing library. 4. Implement the backend: Create an Express.js server that accepts Markdown content and returns HTML. 5. Implement the frontend: Create a simple HTML form for inputting Markdown and JavaScript to handle the form submission and display the converted HTML. 6. Test the application: Ensure the application works as expected. ### Subtasks: 1. Set up the project structure: • Create a directory structure for the project. • Create initial files for the backend and frontend. 2. Initialize a Node.js project: • Run npm init to create a package.json file. 3. Install necessary packages: • Install Express.js and a Markdown parsing library like marked . 4. Implement the backend: • Set up an Express.js server. • Create a route to accept POST requests with Markdown content. • Use the Markdown parsing library to convert the content to HTML. • Return the HTML to the client. 5. Implement the frontend: • Create an HTML form for users to input Markdown. • Write JavaScript to handle form submission. • Send the Markdown content to the backend. • Display the returned HTML content on the page. 6. Test the application: • Manually test the application to ensure it works as expected.
必要なステップの列挙が終わると、subtasksに記載の内容に従って、必要なファイルを作成しながら開発を進めます。以下は実際の出力結果です。
## Creating the Project Structure First, create a base directory for the project, which we'll refer to as markdown-to-html-converter . Inside this directory, we'll create two subdirectories: src for the server code and public for the static files. • markdown-to-html-converter/ • src/ (for server-side code) • public/ (for client-side code) Next, we'll create the initial files: • A server file in the src directory. • An HTML file and a JavaScript file in the public directory. Let's create these files with some initial content. ### Server File • src/server.js: const express = require('express'); const app = express(); const PORT = process.env.PORT || 3000; app.use(express.static('public')); app.use(express.json()); app.listen(PORT, () => { console.log(`Server is running on http://localhost:${PORT}`); }); This code initializes an Express.js server that serves static files from the public directory and listens on a specified port. ### HTML File for Frontend • public/index.html:Markdown to HTML Converter Markdown to HTML Converter
This HTML file includes a textarea for inputting Markdown, a button to trigger the conversion, and a div to display the converted HTML. ### JavaScript File for Frontend • public/script.js: document.getElementById('convertBtn').addEventListener('click', async () => { const markdownText = document.getElementById('markdownInput').value; // Placeholder for sending the Markdown to the backend and displaying the result }); This JavaScript file adds an event listener to the convert button. When clicked, it will send the Markdown text from the textarea to the backend for conversion. The response will then be displayed in the htmlOutput div. The actual implementation of sending the request and displaying the response will be added later. Next, we will initialize a Node.js project and install the necessary packages. ? To continue with the plan, we'll initialize a Node.js project in our markdown-to-html-converter directory and install the necessary packages. This involves creating a package.json file to manage our project dependencies and then installing Express.js for our web server framework, along with a Markdown parsing library such as marked to convert Markdown to HTML. ### Initialize a Node.js Project Navigate to the root of your project directory ( markdown-to-html-converter ) in your terminal and run the following command to initialize a new Node.js project. This will create a package.json file in your project directory. npm init -y ### Install Necessary Packages Still in the root of your project directory, run the following commands to install Express.js and marked , a popular Markdown parsing library. npm install express npm install marked ### Implement the Backend Now, let's implement the backend functionality to accept Markdown content via a POST request, convert it to HTML using the marked library, and return the HTML content to the client. • src/server.js: const express = require('express'); const marked = require('marked'); const app = express(); const PORT = process.env.PORT || 3000; app.use(express.static('public')); app.use(express.json()); // Route to handle conversion app.post('/convert', (req, res) => { const { markdown } = req.body; if (!markdown) { return res.status(400).send('No Markdown content provided'); } const html = marked(markdown); res.send({ html }); }); app.listen(PORT, () => { console.log(`Server is running on http://localhost:${PORT}`); }); This code adds a POST route /convert to our Express.js server that accepts Markdown content in the request body, converts it to HTML using the marked library, and returns the HTML content in the response. ### Implement the Frontend JavaScript Next, we need to update the frontend JavaScript to handle the form submission, send the Markdown content to the backend for conversion, and display the converted HTML content on the page. • public/script.js: document.getElementById('convertBtn').addEventListener('click', async () => { const markdownText = document.getElementById('markdownInput').value; const response = await fetch('/convert', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ markdown: markdownText }), }); const result = await response.json(); document.getElementById('htmlOutput').innerHTML = result.html; }); This code sends the Markdown content to the backend /convert route using a POST request and displays the returned HTML content in the htmlOutput div. ### Testing the Application Finally, you should test the application to ensure it works as expected. Start the server by running node src/server.js in your terminal, open your browser, and navigate to http://localhost:3000 . Enter some Markdown in the textarea, click the "Convert" button, and verify that the Markdown is correctly converted to HTML and displayed on the page. All tasks have been completed.
plandex changeで人間が変更を確認し、plandex applyで変更を適用します。terraformのplanとapplyに近い感覚です。
実際に生成されたファイルを実行してみると、エラーがでるので何度か、エラーの内容をpalndex tellで与えながら、ファイルを修正してもらい最終的に、以下のような画面ができました。必要最低限の機能で仕様を満たしたものができていますね。
中身を深堀りしてみる
一番メインのシステムプロンプトは、こちら(https://github.com/plandex-ai/plandex/blob/main/app/server/model/prompts/create.go)にあります。面白いところは、計画を立てるのに十分な情報が足りなければ追加の情報を要求しなさいと指示していることと、タスクが大きすぎて1つの応答で答えられない場合はサブタスクに細分化しなさいと明示していることですね。
処理の流れとしては、LLMに指示を与えて作業の計画とサブタスクを作成します。どこまでタスクが進んでいるかはpostgresqlのDBを裏側に持っており、そこで状態管理しています。変更の適用はどのファイルをどのように変更するかを持っており、textをreplaceする形で適用します。状態管理はDB、計画とコードの修正はLLMに任せるといった非常にシンプルな形です。
まとめ
触ってみたところコード生成ツールが今すぐにエンジニアの業務を置き換えることはないという感覚ですが、仕組みを理解して、将来訪れるかも知れないAIツールで開発が完結する時代に対応できるようにするしかないと思いました。業務効率化という意味では、GitHub Copilotの補完やCursor Editorのドキュメント検索機能などをうまく駆使しするほうがまだまだ価値を発揮できそうだなという感覚です。
最後に
グループ研究開発本部 AI研究開発室では、データサイエンティスト/機械学習エンジニアを募集しています。ビッグデータの解析業務などAI研究開発室にご興味を持って頂ける方がいらっしゃいましたら、ぜひ募集要項一覧からご応募をお願いします。 一緒に勉強しながら楽しく働きたい方のご応募をお待ちしております。
グループ研究開発本部の最新情報をTwitterで配信中です。ぜひフォローください。
Follow @GMO_RD