Preview 1
Aincarn Lab / コード生成
コード生成AI比較ログ
同じ小さな実装課題を主要AIに依頼し、完成物の動作、UI、コード品質、要件の満たし方を比較します。生成物はページ内プレビューでも確認できます。
TODOアプリの完成物でコード生成力を比較
同じTODOアプリ課題で、完成物の動作、UI、コード品質、要件充足を比較しました。Fable5は追加・完了切替・削除の基本要件を満たし、完成物として最も扱いやすい結果でした。
Evaluation
出力条件への評価サマリー
条件「ブラウザで使えるシンプルなTODOアプリを作る」に対する各モデルのスコアです。5点満点で、合計が高い順に並べています。
Rubric
同一比較回の相対評価として採点します
点数は同じタスク、同じ出力条件、同じ比較回の中での相対評価です。モデル更新や比較対象が変わると、同じ5点でも水準は変わります。そのため過去ログでは当時の順位、点数、評価理由を保存して、現在の評価と混ざらないようにしています。
Evaluation Focus
- 指定された機能が実際に動き、完成物として確認できるか。
- UI、コード品質、要件充足、修正しやすさを分けて評価する。
- 見た目だけでなく、保存、削除、状態変更などの挙動を重視する。
5点
同じ比較回の中で、対象モデルの中では最も条件適合度が高い。別回の5点と同一水準とは限らない。
4点
同じ比較回の中で上位水準。明確な強みがあるが、5点モデルと比べると補う点がある。
3点
同じ比較回の中で中位水準。使える要素はあるが、複数の評価軸で不足が残る。
2点
同じ比較回の中で下位水準。条件の一部は満たすが、主要な用途では選びにくい。
1点
同じ比較回の中で最も条件適合度が低い。出力・完成物を大きく見直す必要がある。
| 評価項目 | Fable5 Ultracode | GPT5.5 非常に高い | Gemini3.1 Pro(High) |
|---|---|---|---|
| 完成物の動作 | 5 | 4 | 4 |
| UIの使いやすさ | 5 | 5 | 4 |
| コード品質 | 5 | 5 | 4 |
| 要件の満たし方 | 5 | 4 | 3 |
| 修正しやすさ | 4 | 4 | 4 |
Data Prompt
比較データ収集用プロンプト
各AIに同じプロンプトを渡し、回答、実行日、モデル名、評価項目を分けて記録します。
あなたはAI比較サイト「Aincarn Lab」の検証対象AIです。 以下の条件で、ブラウザ上でそのまま動かせる小さなWebアプリを作成してください。 課題: ブラウザで使えるシンプルなTODOアプリを作る 要件: - タスクを追加できる - 完了状態を切り替えられる - 削除できる - localStorageに保存する - モバイルでも見やすい 出力条件: - HTML、CSS、JavaScriptを1つのHTMLファイルにまとめる - 外部ライブラリ、外部CDN、画像、ビルドツールは使わない - そのまま.htmlとして保存すれば動くコードを出す - コード全文を1つのコードブロックで出す
Live Preview
生成アプリを触って比較
各モデルのHTML出力を、ページ内の隔離プレビューとして表示しています。外部通信や親ページへの干渉を避けるため、sandbox付きiframeで実行します。
Preview 2
GPT5.5 非常に高い
Preview 3
Gemini3.1 Pro(High)
Per-model output
モデル別アウトプット
各モデルの出力を、モデルごとに切り替えて確認できます。内容は要約せず、読みやすい位置で改行だけ補っています。
Model
Fable5 Ultracode
Model Output
検証出力
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>TODOアプリ</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Hiragino Sans", "Noto Sans JP", sans-serif;
background: linear-gradient(160deg, #eef2ff 0%, #fdf2f8 100%);
min-height: 100vh;
display: flex;
justify-content: center;
padding: 24px 16px;
color: #1f2937;
}
.app {
width: 100%;
max-width: 480px;
}
h1 {
font-size: 1.5rem;
text-align: center;
margin-bottom: 4px;
}
.counter {
text-align: center;
font-size: 0.85rem;
color: #6b7280;
margin-bottom: 16px;
}
form {
display: flex;
gap: 8px;
margin-bottom: 16px;
}
#task-input {
flex: 1;
min-width: 0;
padding: 12px 14px;
font-size: 1rem;
border: 1px solid #d1d5db;
border-radius: 10px;
background: #fff;
outline: none;
}
#task-input:focus {
border-color: #6366f1;
box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.15);
}
form button {
padding: 0 20px;
min-height: 44px;
font-size: 1rem;
font-weight: 600;
color: #fff;
background: #6366f1;
border: none;
border-radius: 10px;
cursor: pointer;
flex-shrink: 0;
}
form button:active { background: #4f46e5; }
ul { list-style: none; }
li {
display: flex;
align-items: center;
gap: 12px;
background: #fff;
border: 1px solid #e5e7eb;
border-radius: 12px;
padding: 12px 14px;
margin-bottom: 8px;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
}
li input[type="checkbox"] {
width: 22px;
height: 22px;
accent-color: #6366f1;
cursor: pointer;
flex-shrink: 0;
}
li .text {
flex: 1;
font-size: 1rem;
line-height: 1.4;
word-break: break-word;
cursor: pointer;
}
li.done .text {
text-decoration: line-through;
color: #9ca3af;
}
.delete-btn {
width: 44px;
height: 44px;
margin: -8px -8px -8px 0;
font-size: 1.1rem;
color: #9ca3af;
background: none;
border: none;
border-radius: 8px;
cursor: pointer;
flex-shrink: 0;
}
.delete-btn:active {
color: #ef4444;
background: #fef2f2;
}
.empty {
text-align: center;
color: #9ca3af;
font-size: 0.9rem;
padding: 32px 0;
}
</style>
</head>
<body>
<main class="app">
<h1>TODO</h1>
<p class="counter" id="counter"></p>
<form id="task-form">
<input id="task-input" type="text" placeholder="タスクを入力..." autocomplete="off" maxlength="200">
<button type="submit">追加</button>
</form>
<ul id="task-list"></ul>
<p class="empty" id="empty" hidden>タスクはありません。上から追加してください。</p>
</main>
<script>
(function () {
"use strict";
var STORAGE_KEY = "todo-app-tasks";
var form = document.getElementById("task-form");
var input = document.getElementById("task-input");
var list = document.getElementById("task-list");
var counter = document.getElementById("counter");
var empty = document.getElementById("empty");
var tasks = load();
function load() {
try {
var raw = localStorage.getItem(STORAGE_KEY);
var data = raw ? JSON.parse(raw) : [];
return Array.isArray(data) ? data : [];
} catch (e) {
return [];
}
}
function save() {
try {
localStorage.setItem(STORAGE_KEY, JSON.stringify(tasks));
} catch (e) {
// ストレージ無効
・容量超過時はメモリ上のみで動作を継続
}
}
function render() {
list.textContent = "";
tasks.forEach(function (task) {
var li = document.createElement("li");
if (task.done) li.classList.add("done");
var checkbox = document.createElement("input");
checkbox.type = "checkbox";
checkbox.checked = task.done;
checkbox.setAttribute("aria-label", "完了切り替え: " + task.text);
checkbox.addEventListener("change", function () {
toggle(task.id);
});
var span = document.createElement("span");
span.className = "text";
span.textContent = task.text;
span.addEventListener("click", function () {
toggle(task.id);
});
var del = document.createElement("button");
del.type = "button";
del.className = "delete-btn";
del.textContent = "✕";
del.setAttribute("aria-label", "削除: " + task.text);
del.addEventListener("click", function () {
remove(task.id);
});
li.appendChild(checkbox);
li.appendChild(span);
li.appendChild(del);
list.appendChild(li);
});
empty.hidden = tasks.length > 0;
var remaining = tasks.filter(function (t) { return !t.done; }).length;
counter.textContent = tasks.length === 0
? "今日のタスクを追加しましょう"
: "残り " + remaining + " 件 / 全 " + tasks.length + " 件";
}
function add(text) {
tasks.push({
id: Date.now().toString(36) + Math.random().toString(36).slice(2, 7),
text: text,
done: false
});
save();
render();
}
function toggle(id) {
var task = tasks.find(function (t) { return t.id === id; });
if (task) {
task.done = !task.done;
save();
render();
}
}
function remove(id) {
tasks = tasks.filter(function (t) { return t.id !== id; });
save();
render();
}
form.addEventListener("submit", function (e) {
e.preventDefault();
var text = input.value.trim();
if (!text) return;
add(text);
input.value = "";
input.focus();
});
render();
})();
</script>
</body>
</html>Log Archive
比較ログ アーカイブ
検証を更新するたびに、個別ページで積み上げています。
