Log in to leave a comment
No posts yet
CursorやDevinのようなツールは便利です。しかし、内部で正確に何が起きているのか把握しにくく、時には自分が意図しない形でコードをバラバラに切り刻んでしまうこともあります。バックエンド開発者なら、Pythonの標準ライブラリとLLM APIを組み合わせて、自分自身に最適化されたエージェントを自作する方が、はるかに経済的で確実です。
エージェントが単にコードを書く段階を超え、ターミナルコマンドを直接実行できるようにするには、subprocessモジュールを精巧に扱う必要があります。むやみにshell=Trueオプションを使うと、シェルインジェクション攻撃にさらされたり、タイムアウト時にプロセスが終了せずゾンビのように残ってしまう問題が発生します。
直接実装する場合は、subprocess.run()呼び出し時にshell=Falseを設定し、コマンドをリスト形式で渡してください。タイムアウトは30秒程度と短めに設定し、TimeoutExpired例外が発生したら直ちにprocess.kill()を呼び出してリソースを回収する必要があります。モデルに実行結果を伝える際も、内容をすべて送る必要はありません。テキストが1,000文字を超える場合は、最後の20行を中心に切り取って返してください。トークンの浪費を防ぎつつ、モデルがエラーの原因を把握するには十分な情報です。
会話が長くなるほど、コンテキストウィンドウに蓄積されるデータはコストの爆発につながります。Anthropicの発表によると、Claude 3.5モデルでcache_controlマーカーを活用した場合、キャッシュされたデータを読み取るコストを最大90%削減できます。100万トークンあたり0.30ドルという水準です。
コストを抑えるには、システムメッセージとユーザー入力を厳格に分離してください。プロジェクト全体のファイルツリー構造のように変化しない情報は、システムプロンプトの上部に固定し、キャッシュポイントとして設定します。会話履歴が積み重なってトークンが溢れるときは、tiktokenで量を計算した後、古いメッセージを別のLLM呼び出しで要約する階層的な要約方式を使うと効果的です。このように要約されたコンテキストのみを上部に維持し、最新のメッセージを付け加えるスライディングウィンドウを適用すれば、長い開発セッションでもコストを従来比で40%以上削減しながら、モデルの推論精度を守ることができます。
エージェントにファイル全体を再度出力させる方式は、非効率で低速です。出力トークンが多くなるほど、モデルが中間のコードを省略したり、誤った内容を出力したりする確率も高まります。いわゆる"エディット・トリック(Edit Trick)"と呼ばれる方式は、修正が必要な箇所の前後のテキスト(Anchor)だけを探して置換するように誘導します。この技法は、実際のデータにおいて出力トークン量を最大86%削減する効果があります。
Pythonのre.sub()を活用し、特定のXMLタグや正規表現で送られてきた修正事項のみをローカルファイルに適用する機能を構築してください。また、すべての技術文書をプロンプトに入れる代わりに、LanceDBのような軽量なベクトルDBを連携させ、必要な文書の断片だけを取得するように設計すべきです。この構造を整えれば、ファイルの修正速度は体感で79%以上速くなり、大型ファイルの作業時にモデルが迷走するという慢性的な問題を解決できます。
人間がいちいちデバッグメッセージをコピーしてモデルに貼り付ける手間を省くべきです。エージェントがコードを作成する前に、pytestベースのテストコードを先に書くように仕向けます。
テストが失敗した場合に発生するTracebackの全文を加工せずにモデルへ投げ返し、自ら修正させるフィードバックループを構築すればよいのです。ただし、rmやdeployのような危険なコマンドについては、Pythonのinput()関数を使用してユーザーの承認を経るガードレールを必ず挿入しなければなりません。この循環構造が完成すれば、開発者はエージェントが提示したgit diffの要約を確認し、コミットボタンを押すだけで済みます。
結局のところ、エージェント構築の核心は華やかなフレームワークではなく、ターミナルとLLMの間でデータをいかに精巧に精製し、キャッシングするかにあります。自分で書いた600行のPythonコードが、数万行のブラックボックスツールよりも、あなたの意図をより正確に反映してくれるはずです。