Mistal.aiからMistral 3.1 Smallをベースにしたコーディング専用モデルDevstralが出ていたので、これを使ってエージェントを作ろうと思ったのです。
Devstral | Mistral AI
Devstralは、24Bというサイズで他の大きなオープンウェイトモデルも凌駕するコーディング性能を出しています。
ベンチマークは当てにならないことも多いですが、使い比べた実感としても確かにQwen3 235B-A22BやDeepSeekよりもコードを書くという印象です。
これを、以前作った、Tool Use(Function Calling)を使った雑なコーディングエージェントで使ってみようと思ったわけです。
LangChain4Jで雑なAIコーディングエージェントを作る - きしだのHatena
けど、DevstralがTool Useに対応してないようで、うまく動きませんでした。
でもRoo Codeは動いてるな、とシステムプロンプトを見てると、独自にXML形式を定義して出力させています。
ということで、XML形式を指定して自力でパースするのを試してみました。
システムプロンプトはこんな感じ。CDATA使うなというのはGemma3のために書いてるんですが、ここまで書いてもGemma3はCDATAを使うので、ちょっとあきらめ。
you are coding agent. generate source codes following user instruction. you must generate whole code to run the user intended system including configuration and build script. you must make readme.md file including the feature, file structure, how to build, how to run. all generated source codes including readme.md must be in the xml format below. code tag start and end must be separated line. <source> <filename>path of code</filename> <code> the code that must use entity reference. not use use CDATA tag. </code> </source>
そうするとだいたいこんな出力になります。
出てきた出力を、こんな感じのパーサーで解析します。
void consume(char ch) { buf.append(ch); if (state == State.PLAIN) { handler.plain(ch); } if (ch != RET) { return; } String str = buf.toString(); buf.setLength(0); switch (state) { case PLAIN -> { if (str.startsWith("```")) { formatted = !formatted; } else if (str.trim().equals("<source>")) { state = State.IN_XML; handler.sourceStarted(); } } case IN_XML -> { if (str.startsWith("<filename>")) { String name = str.substring("<filename>".length(), str.length() - "</filename>\n".length()); handler.filename(name); } else if (str.trim().equals("<code>")) { state = State.IN_CODE; } else if (str.trim().equals("</source>")) { state = State.PLAIN; handler.sourceEnded(); }else { System.out.println(str); } } case IN_CODE -> { if (str.trim().equals("</code>")) { state = State.IN_XML; } else { String code = str.replaceAll("<", "<").replaceAll(">", ">" .replaceAll(""", "\"").replaceAll("&", "&")); handler.code(code); } } } }
なんか いい感じに動きました。6倍速で、実際は3分くらいで生成が終わってます。
ここではcreate tableしてなくてエラーになるので「テーブル定義のSQLがないよ」と指示してあげると、schema.sqlを作ってくれました。
エラーが出たときにエラーログを渡すと修正してくれたりもします。
簡単なコードだけど、想像以上にちゃんと動いてくれました。
完全なコードはこちら。
https://gist.github.com/kishida/bc7cec2d036c906111a5be93f1159870