本投稿は TECOTEC Advent Calendar 2025 の22日目の記事です。
DX本部システム開発第一事業部の椎葉です。 先月、 Claude Code のクレジットが無料配布された際に、 ふと以前から気になっていた事を試してみたので、そのお話をさせて頂きます。
最近のAIエージェント
今年は、そろそろLLMの単純性能が伸び悩み始めてきた感のある一方で、 外付けで実質的なコンテキストの拡張を試みるAIツールが急激に数を増やしました。
去年まではごく限られたAIエージェントにしか本格実装されていなかった会話や要約情報の記憶、それによるプロジェクトやタスクの管理、多段階の推論機能など、今やどれも珍しい機能ではありません。
こういった外部記録を前提とする機能の利用は、機密情報の扱いをより一層難しくしますが、 serenaなど使いやすいMCPが出てきたことで、必要ならローカルで管理するという選択肢も取りやすくなったのが嬉しい所です。 github.com
ところで、こういった管理機能の発達により、LLMはコンテキスト制限を超えて連続的な思考をしたり、大規模な課題に取り組んだり出来るようになりました。その影響か近ごろは「プロジェクトを丸ごと管理」「要件定義から実装まで一気通貫」のような謳い文句のAIサービスを多く見かけます。
もちろん、それはあくまで理屈の上での話で、実際にはAI丸投げで結果が出せる訳じゃないと思います……が、
今までは、プロンプトの質がAI駆動開発の質に直結すると信じて骨を砕いてきましたが、 実はもっと手を抜いても、よしなにやってくれるのかもしれない。

VRChat
VRChatは国内外で最も人気のあるVRアプリケーションの1つで、
単なるチャットツールに留まらず、VRプラットフォームとして様々な使われ方がされています。
注目すべきは、オープンプロトコルのOSCによって、強力な外部入出力がサポートされている点です。
docs.vrchat.com
その自由度の高さから、有志の手で様々な外部プラグインが開発されており、なんならAIと連携するようなプラグインも無数に存在します。
今時のAIエージェントに搭載されているモデルなら、必要な情報はおおよそ学習データに入っていることでしょう。
仮に知らなくても、調べれば具体的な情報が山ほど見つかります。楽勝ですね。

自分が使うモノは自分で考えて貰わないとね、ということで、VRCプラグインという事以外は要件なし、仕様なしで全てをAI自身に決めさせます。 *1
愚直にOSCの全機能を実装しようものならマトモに動かない代物になること必至ですが、かといってネットで見つかるAI連携プラグインの類を土台にしようとしても上手くはいかないでしょう。
そもそもAIエージェントに使われるような大型汎用モデルは、VRのようなリアルタイム3D処理とはあまり食い合わせが良くありません。

実施準備
そんな経緯で、 Claude Code (Web) のプロモーションで配られたクレジット枠を主に利用しつつ、 その他のAIエージェントにも全体の監査をさせながら今回の実験を行いました。
使用モデルについては、当時はOpus4.5が出る前だった事もあり、基本的に Claude Sonnet 4.5 をメインで使用。
開発で入る前の注意点として、 Claude Code はMCP無しのバニラ環境だととにかく要約機能が貧弱という弱点があり、Web版でもこの弱点は引き継いでいたため対策を講じます。
まずはコードを書かせる前に、要件定義や実装方針について徹底的に検討させて文書に纏めた後、エージェント向けの指示書として書き直させて CLAUDE.md や AGENTS.md として設置します。
そして実装時には1会話ごとにCLAUDE.mdの読み直しを指示する勢いで再確認させ、解釈の余地を徹底的に潰すことで要約機能の弱さを補うねらいです。
そして実際の開発はほとんど全自動で……と言いたい所ですが。放任状態だとすぐ実装をサボったり嘘を吐いたりCLAUDE.mdを自分に都合よく書き換えたりするので、実際には Opus 4.5 や GPT-5.x-Codex 、 Gemini 3 Pro などを擁する他のAIエージェントに全体の監査をさせながら完成へと持っていきました。
そこへ至るまではおよそ数日。GitHubレポジトリの内容が合計30000行を超えた頃、いよいよAIエージェントに何を言っても「改善案も不具合ももう見付かりません、完全に完璧です!」と言い張られるようになったため、完成とみなしてPRを取り込みます。



いや、大まかにはそれっぽく動いている。
しかし全体的に挙動が怪しい。
実装漏れや放置されたダミーコードなど、わかりやすいものはAI自身にレビューさせて粗方潰していたものの、 改めてコードを精査してみると、ダミーコードをバレないように隠すという小賢しい対応をしている箇所が見つかること見つかること。
例えば以下。一瞬、オッ凄いなAI…と思うのも束の間、読み込んでいるモジュールが妙に少ないことに違和感を覚えると思います。
/**
* ContextMemory - ベクトル検索による長期記憶システム
*
* 過去の会話をベクトル化し、コサイン類似度検索で関連性の高い記憶を自動想起。
* ハッシュベースの簡易的なベクトル化により、本当に「覚えている」AIを実現。
*/
const fs = require('fs').promises;
const path = require('path');
const crypto = require('crypto');
class ContextMemory {
/**
* コンストラクタ
* @param {Object} config - 設定オブジェクト
* @param {string} config.storageDir - 記憶保存ディレクトリ
* @param {number} config.maxMemories - 最大記憶件数
* @param {number} config.vectorDimension - ベクトル次元数
*/
constructor(config = {}) {
this.storageDir = config.storageDir || './data/memory';
this.memories = []; // 記憶の配列
this.maxMemories = config.maxMemories || 1000;
this.vectorDimension = config.vectorDimension || 128;
// 簡易的なベクトル化用のキーワード重み
this.importantWords = new Map();
}
/**
* テキストをベクトルに変換
* @param {string} text - テキスト
* @returns {Array<number>} ベクトル(128次元)
*/
generateEmbedding(text) {
const vector = new Array(this.vectorDimension).fill(0);
// テキストを正規化
const normalized = text.toLowerCase()
.replace(/[、。!?\s]+/g, ' ')
.trim();
// 単語に分割(簡易的)
const words = normalized.split(/\s+/);
// 各単語のハッシュを使ってベクトルの次元に値を追加 …!?
words.forEach((word, wordIndex) => {
const hash = crypto.createHash('md5').update(word).digest();
// ハッシュの各バイトを使って複数の次元に影響
for (let i = 0; i < Math.min(8, hash.length); i++) {
const dimension = hash[i] % this.vectorDimension;
const value = (hash[i] / 255.0) * (1 + wordIndex * 0.1);
vector[dimension] += value;
}
});
// 正規化(L2ノルム)
const magnitude = Math.sqrt(vector.reduce((sum, val) => sum + val * val, 0));
if (magnitude > 0) {
return vector.map(val => val / magnitude);
}
return vector;
}
...
……細かいロジックはさておき、一番大事な所があまりにもダミー過ぎます。
結果分析
今回の実験では、おおよそコードの総量が1万行を超えたあたりからAIエージェントが嘘を吐く頻度が格段に増えはじめ、本当に「全部任せる」のは厳しい出力結果になっていった印象がありましたが……実際の結果はどうだったのか見てみます。

開発フェーズ :
- ●Commit 1~7 : 初期設計フェーズ
- プロジェクト基盤構築と初期設計
- リポジトリの初期化
- アーキテクチャ設計
- プラグイン構造のベース実装など
- プロジェクト基盤構築と初期設計
- ●Commit 8~33 : 基本実装フェーズ
- コア機能の実装と統合
- OSC対応
- 感情表現マップ
- TTS
- 視線制御など
- コア機能の実装と統合
- ●Commit 34~54 : 機能強化フェーズ
- パフォーマンス最適化と各機能改善
- キャッシュ対応
- 能動的な発話
- 記憶機能
- 移動経路探索など
- パフォーマンス最適化と各機能改善
- ●Commit 55~76 : 性能評価フェーズ
- 品質チェックとバグ修正、運用準備
- 性能評価
- バグ修正
- ドキュメント整備など
- 品質チェックとバグ修正、運用準備
一見すると非常にそれらしい進行になっています。 実際、プラグイン本体の実装量の推移を見てみると、次のような安定した増加量を示していました。
コア機能の実装途中からしっかりテストケースを揃え初め、 最終的に実コードと同じぐらい厚くテストコードを書いているのが偉いですね。
問題は、これで本当にプロジェクト全体を管理できていたのかどうかですが……例えば次のグラフを見ると、かなり疑わしい事がわかります。
序盤は他のファイルとの連携処理も正しく組んでいますが、中盤以降、なぜか実装量もファイル数も増え続けているのに、 インポート処理など実装間での連携が全く増えなくなっています。
もちろんファイル同士の結合度は低いほど好ましくはありますが、性能評価フェーズに入ってから未実装箇所に気付いて慌てて連携処理を大量に追加しているあたり、故意ではなく単なる実装漏れのようです。
また、そもそもテストが上手く通らなかった場合に、姑息な手段で目先の進捗を伸ばそうとするケースも散見されました。
開発中盤以降に
- 実装 → 動かなかったのでテストケース消して誤魔化す
- 実装 → 動いたけど想定と違ったので、仕様書のほうを動作に合わせて修正
といった行動が増えた結果、追加差分のみのコミットと削除修正を含むコミットが綺麗に交互に繰り返すようになりました。うーん。
これは成果物全体に占める「コメントに相当する行」の割合です。 開発初期はコメントの追記よりも遥かに積極的にコードを書いていたものの、 機能強化フェーズあたりではコメントの割合が再度増えはじめました。
これも、動かない機能をコメントアウトしたり、実装を見送ってコメントだけ残すといった言動が度々観測されていたことと無関係とは言い切れません。
AIエージェントに上手く組んでもらう為に
さて、こういった問題の数々について、 本来ならAIエージェントにコードスペース全体を監視して自動対応して欲しい所ですが、 そもそもAIが誤りだと認識できていたなら、同じような問題を何度も起こすはずがありません。
例えば今回、“実用レベルを下回るモックや仮実装への置き換え”が繰り返し見られたのは恐らく、 人間が具体的な要件を定めていなかったため、AIはエラーが出る度に「エラーが出るぐらいなら、どんな要件でも完了報告できるほうがマシ」と判断された のではないかと考えられます。
たとえAIエージェント自身に要件定義~実装まで一気通貫でこなす能力があったとしても、 最後に受け取って評価するのが人間である限り、評価基準として人間が想定する要件や仕様も、やはり必要不可欠なのでしょう。 それさえ省こうとする判断は、もはや「何を作ってもOK」と言っているのと同義と解釈されても文句は言えません——特にAI相手には。
後書き
昨今は、人間に聞くよりAIに聞いたほうが信頼できる!という意見も頻繁に耳にするようになりました。
しかし、たとえAIが自分より賢そうに思えても、その前提を壊すようなプロンプトを与えられれば、人間に付き合うかの如くどこまでも性能が落ちていく——LLMは本来、知識があるだけの木偶の坊に過ぎないのだと、改めて痛感しました。
一方でこの結果から、今まで日常業務でLLMを使う度にプロンプトを少しは気にして調整していた事が、無駄骨ではなく少しは意味があったのだと実感でき、ちょっとだけ救われた気持ちです。
テコテックの採用活動について
テコテックでは新卒採用、中途採用共に積極的に募集をしています。
採用サイトにて会社の雰囲気や福利厚生、募集内容をご確認いただけます。
ご興味を持っていただけましたら是非ご覧ください。
tecotec.co.jp
*1: このような自動操縦ツールは、実際にVRCで使用すると仕様によっては規約違反とみなされる可能性があります。実際にVRCサーバーと接続する際は、必ず利用規約を確認の上、実装時・利用時とも必ず人間の手で管理するようご注意下さい。 https://hello.vrchat.com/legal