JITERAとは
JITERA は、要件定義やFigmaファイルを読み込ませてソフトウェア開発を行えるAIを活用したプラットフォームです。
このようなAIツールで、どこまでソフトウェアを作ることができるのか興味があったので、実際に利用してみました。
ChatGPTやCursorなどのチャット系AI製品と違い
コードが生成されるまでのステップが細かく分かれているのが特徴です。
システム開発の複雑さを、AIチャットベースで解決するのではなくて
細かいステップに分割することで解決するようなアプローチを狙っているのだと思います。
今回は、家族共有カレンダーのシステム開発を通して JITERA を紹介します。
1. プロジェクトの作成
プロジェクト作成時には、フロントエンドとバックエンドのプログラミング言語を設定できます。
フロントエンドと、バックエンドがかなり自由に選べるので
技術的に枯れて、ノウハウが多いRailsで手堅くロジックを組んでいきつつ
ユーザに近いフロントは最近の技術で仕上げたいなどの組み合わせも可能です。
今回は、そういうイメージでフロントは Next.js
バックエンドは Rails を選択しました。
2. デザインのインプット
今回は、家族共有カレンダーをイメージしたFigmaファイルを読み込ませてみました。
このようなFigmaを入力すると、次のユースケースのような文章などを自動的に生成してくれます。
次のUIは基本的の操作画面だけ抜粋してスクショしています。
Figmaから要件定義を自動生成してくれるのもAIらしい機能で良い感じですね。
3. ユースケース
ユースケースはJITERAとしては
いわゆるどういう風に使われるかを定義して
後の作業の指示を出していくために使われる文章のようです。
先程の、Figmaから要件定義が自動生成されています。
なお、前述の図にあるようにFigmaなしで要件定義から始めることもできるようです。
生成された要件定義は、文章を直接修正することもできます。
各ユースケースには以下の情報が含まれます:
- Actors(想定利用者)
- Preconditions(前提条件)
- Main Flow(メインの流れ)
- Alternative Flows(代替の流れ)
- Postconditions(正常終了時のあるべき状態)
このあたり、しっかり項目に分けることで
後の精度を上げるような工夫をしている雰囲気を感じますね。
4. チケット出力
要件定義から、作業を小分けにチケットとして分割してくれています。
こちらも、要件に対して、実際の作業をチケットに書き出すようなイメージで
実際の開発イメージに近いなと思いました。
各ユースケースに対して、ユーザーストーリーをチケットという形で分割されます。
チケットのGenerateを選択すると、次のシステム設計に関する項目が自動生成されます。
コードだけではなくて、チケットに紐づくDatabaseや
ビジネスロジック、API設計などが同時に出力されていました。
5. システム設計
Database
チケットからDBのER図のようなものが生成されています。
こちらも、テーブル、カラム、リレーション、インデックス等を追加および削除することができます。
ビジネスロジック設計
チケットから、ビジネスロジックが生成されます。
こちらも、直接編集することができます。
API設計
最後に、API設計も生成されているので
方向性が間違っていないかを確認して補正などを行います。
エンドポイント、メソッド、パラメータ、バリデーション、レスポンスメッセージ等の一般的なRestAPIの内容が記述されています。
6. コードの生成
JITERA は GitHub と連動してくれていて
コードレビューもプルリクエストとして GitHub 上で扱われていていい感じです
AIと協調して、コーディングを行えている感じがありますね。
設計から、ソースコードが提供されるので
万が一 JITERA のユースケースからはみ出てしまっても
自前で加工すれば何とかなるというのは良さそうだなと思いました。
一部抜粋ですが、次のようなコードが生成されていました。
import { NextApiRequest, NextApiResponse } from 'next'
export default function handler(req: NextApiRequest, res: NextApiResponse) {
const status = {
uptime: process.uptime(),
responseTime: process.hrtime(),
message: 'OK',
timestamp: Date.now(),
}
res.status(200).json(status)
}
import type { NextApiRequest, NextApiResponse } from 'next'
export default function handler(_: NextApiRequest, res: NextApiResponse) {
res.setHeader('WWW-authenticate', 'Basic realm=""Secure Area""')
res.statusCode = 401
res.end(`Auth Required.`)
}
import { useState } from 'react'
import { useTranslation } from 'next-i18next'
import { Button } from '@components/atoms/Button'
import { Toast } from '@components/atoms/Toast'
import { DefaultPageProps } from '@interfaces/page'
import { useQueryExamples } from '@services/example'
import {
useAuthenticationData,
useExampleAuthenticationMutation,
useLogoutMutation,
} from '@services/authentication'
import styles from './index.module.css'
export type ExampleProps = DefaultPageProps
function ExamplePage(props: ExampleProps): JSX.Element {
const { t } = useTranslation()
const [params, setParams] = useState<{ page: number }>()
const authenticationData = useAuthenticationData()
const { data, isLoading } = useQueryExamples(params, { enabled: !!authenticationData })
const exampleAuthenticationMutation = useExampleAuthenticationMutation()
const logoutMutation = useLogoutMutation()
const handleNext = () => setParams((old) => ({ ...(old || {}), page: (old?.page || 1) + 1 }))
const handleAuthentication = async () => {
if (!authenticationData) {
await exampleAuthenticationMutation.mutateAsync({
table: 'example',
username: 'example',
})
Toast.success(t('example.login_success'))
} else {
await logoutMutation.mutateAsync({})
Toast.success(t('example.logout_success'))
}
}
return (
<div className={styles.page_container}>
<div className={styles.container}>
<div className={styles.center_card}>
<Button
title={(authenticationData ? t('example.logout') : t('example.login')) || ''}
onClick={handleAuthentication}
/>
{authenticationData ? (
<>
<pre>{!isLoading ? JSON.stringify(data || {}, null, 2) : t('common.loading')}</pre>
<Button
disabled={
isLoading || exampleAuthenticationMutation.isLoading || logoutMutation.isLoading
}
title={t('example.next') || ''}
onClick={handleNext}
/>
</>
) : null}
</div>
</div>
</div>
)
}
export default ExamplePage
まとめ
JITERA は、ChatGPTやCursorなどの細かくチャットベースで使っていくAIツールのような感じではなくて
各ステップを細かく、区切りつつAIを連携することで細かいシステム要件を扱っていく
統合的な開発システムであるように思います。
AIチャットでは、凄く汎用的な質問に答えられるという特徴があり
そのような特徴からかなり注目が集まった第4世代AIでありますが
JITERA のように、専門性に寄せて細かいステップを区切りながら
AIに正しい意図を伝えて、生成物の制度を上げていくというアプローチは
今後も増えていくのではないかなと思いました。
このようなコードを書く量を減らしつつ
よりビジネス的にやりたいことに集中できる環境ができていくのは
良いことなんじゃないかなと思います。
ただ、現時点ではプログラマが要らなくなると言うよりかはむしろ
実際にコードが生成されるので、コードレビューなどを通しながら
コード的に正しいかなどを判断していく仕事が増えていくんじゃないかなと思いました。
JITERA で実装されているような、AIを使ってステップをドキュメント化して
そこから生成物を作っていく、方式が今後より発展していくと
チームでのエンジニアと他職種の関係が近くなり
よりユーザーに受け入れられるソフトウェア作りが出来るようになるのではないかと思います。
—
本投稿は、株式会社JITERA様の依頼で執筆しております。