0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

HTTP 境界をなくしたローカルコーディングエージェント: DwarfStar の native agent を読む【第7回/全8回】

本シリーズは、DeepSeek V4 Flash / Pro 専用推論エンジン DwarfStards4)のコードを読み解く連載です。
第7回は、ds4-agent を扱います。OpenAI/Anthropic 互換サーバではなく、推論エンジンを同じプロセスの内側から直接操作するネイティブコーディングエージェントです。

主な参照箇所: README.md, AGENT.md, ds4_agent.c, ds4_kvstore.c, ds4.h

読みどころ: HTTP 境界を外すと、サーバ編で苦労した KV 整合性問題が「構造的に起きない」状態になります。そのトレードオフを読みます。

TL;DR

  • ds4-agent は HTTP API 境界を持たない。UI スレッドとワーカースレッドは分かれるが、ワーカーがライブの ds4_session と KV 状態を直接所有する。
  • README は、エージェントのセッションがオンディスク KV キャッシュそのものとして表現される、と説明している。
  • サーバ編で必要だった OpenAI/Anthropic JSON と DSML の往復変換が薄くなる。エージェントのツールプロンプトは DeepSeek V4 用 DSML を前提に作られ、ツール実行もネイティブ DSML パーサから直接ディスパッチされる。
  • セッションは ~/.ds4/kvcache に保存され、/save, /list, /switch, /del, /strip で操作できる。
  • 保存セッションの ID は最初のユーザープロンプト由来のタイトルと作成時刻から SHA1 で作る。再保存しても同じ同一性を保つ。
  • ツールは read, more, write, edit, search, list, bash, bash_status, bash_stop, google_search, visit_page など。編集プロンプトは DS4 の低速デコードと長文脈を意識して、アンカー付き編集を強く促している。
  • ds4-agent は README 上で明示的に alpha 品質とされ(エンジン本体の beta より前段階)、プロジェクトに後から追加された。とはいえ「ローカル推論をエージェントとして本当に使えるか」を検証するための垂直統合として重要。

1. なぜネイティブエージェントを持つのか

第5回で見た ds4-server は、OpenAI/Anthropic 互換 API を持つために、多くの変換を行っていました。

  • OpenAI のツール呼び出し JSON
  • Anthropic の tool_use ブロック
  • OpenAI Responses のアイテムライフサイクル
  • DeepSeek V4 の DSML テキスト
  • ライブのサンプル済み状態
  • ステートレスなクライアントトランスクリプト

これは既存クライアントと接続するには必要ですが、複雑です。

一方 ds4-agent は、最初から DS4 / DeepSeek V4 のために作られたネイティブエージェントです。README は次のように説明しています。

  • 推論はエージェント自身の内側から制御される
  • ソケット/API 境界がない
  • セッションはオンディスク KV キャッシュそのものとして表現される
  • ツールとシステムプロンプトは DeepSeek V4 Flash / Pro 向けに垂直設計されている

要するに、既存 API 互換ではなく、「このエンジンとこのモデルに最も合うエージェント」を作る方向です。


2. プロセスモデル: UI スレッドとワーカースレッド

ds4_agent.c の冒頭のコメントは、エージェントのスレッドモデルを説明しています。

/* The agent is intentionally a single process: the UI thread owns terminal
 * input/output, while the worker thread owns the live DS4 session and KV state.
 * ... used to render sampled assistant text and DSML tool calls as they arrive.
 */

サーバではクライアントスレッドがリクエストをキューに積み、単一グラフワーカーが処理しました。エージェントでもライブセッションをワーカー側に閉じ込める考え方は同じです。

違うのは、外部の HTTP プロトコルがないことです。UI はターミナル入力と表示を担当し、ワーカーは ds4_session、トランスクリプト、ツール実行、KV の保存/ロードを扱います。

agent_worker には以下のような状態があります。

ds4_session *session;
ds4_tokens transcript;
char session_sha[41];
char *session_title;
uint64_t session_created_at;
bool session_dirty;

ここで transcript はレンダリング済みチャットトークン列、session はライブ KV チェックポイントを持つ実体です。


3. セッションは ~/.ds4/kvcache に保存される

README によると、エージェントのセッションは ~/.ds4/kvcache に保存されます。

主要コマンド

コマンド 役割
/save 現在のセッションを保存
/list 保存セッションを最近の更新順に表示
/switch <sha> セッションを再開
/del <sha> 保存セッションを削除
/strip <sha> 重い KV ペイロードを削除し、レンダリング済みテキストだけ残す

/strip が面白いです。KV ペイロードは大きいため、不要になったらトランスクリプトとタイトルだけ残せます。strip 済みセッションに switch すると、保存されたレンダリング済みテキストを prefill して KV を再構築します。

フル KV セッションなら、switch 後に prefill なしで再開できます。これは README が挙げるネイティブエージェントの利点の一つです。セッションの状態遷移を図にすると、「KV の有無」が中心にあることが分かります。


4. セッションの同一性はタイトルと作成時刻

サーバのディスク KV はレンダリング後バイトプレフィックスの SHA1 をファイル名にしました。エージェントのセッションでは、少し違う同一性を使います。

ds4_agent.c のコメント

/* Modern sessions:
 *   SHA1(title || created_at_le64).kv, where title is the first user prompt and
 *   created_at is preserved across future saves. The title is stored in an
 *   agent-only trailer after the KV payload.
 */

保存済みセッションのファイル名は、最初のユーザープロンプトから作ったタイトルと作成時刻の SHA1 です。再保存してトランスクリプトと KV ペイロードが更新されても、セッションの同一性は変わりません。

これはエージェントの UX に合っています。会話が伸びるたびにファイル名が変わると /switch/list が扱いにくくなります。セッションという単位を安定させるため、プレフィックスハッシュではなくタイトル + 作成時刻を使っています。

ただしファイル形式の中身は第4回で見た KVC / DSV4 と同じ流れです。エージェント専用のタイトルトレーラが追加されるだけです。


5. システムプロンプトは DSML ネイティブ

ds4_agent.c には、エージェント用のツールプロンプトが C の文字列として埋め込まれています。

冒頭は次のような方針です。

  • ローカルワークスペースで動くコーディングエージェント
  • ファイル/システム作業にはツールを使う
  • 大きなファイル内容や大きなコードブロックを回答として出さず、ツールで作成・編集する
  • DSML のツール記述を厳密な構文で書く
  • ツール呼び出しは <think></think> の中に出してはいけない

ツールプロンプトは DeepSeek V4 の DSML トークンを前提にトークナイズされます。

/* The built-in tool prompt is trusted DS4 control text. Tokenize it like a
 * rendered chat prompt so the literal DSML markers in the examples become
 * the model's dedicated DSML token. Do not apply that tokenizer to user text.
 */

ここは重要です。ユーザーテキストに含まれる DSML 風の文字列を制御トークンとして扱ってはいけません。一方、信頼できるシステム/ツールプロンプト内の DSML マーカーは、モデルにネイティブなツール構文として教える必要があります。


6. ネイティブツールのスキーマ

エージェントプロンプトには、利用可能なツールスキーマが直接埋め込まれています。

代表的なツール:

ツール 役割
read テキストファイル / 行範囲を読む
more 前回の read 系出力の続きを読む
write ファイル作成または全置換
edit old/new による正確な単一置換
search ファイル検索
list ディレクトリ一覧
bash シェルコマンド実行
bash_status 長時間実行 bash ジョブの状態確認
bash_stop 実行中の bash ジョブを停止
google_search 可視ブラウザ経由の Web 検索
visit_page URL を可視ブラウザで開いて Markdown 化

ds4_agent.c にはそれぞれの実装関数があります。

static char *agent_tool_read(...);
static char *agent_tool_write(...);
static char *agent_tool_edit(...);
static char *agent_tool_search(...);
static char *agent_tool_google_search(...);
static char *agent_tool_visit_page(...);

サーバ編のように OpenAI のツールスキーマを DSML に変換しているのではなく、最初から DSML のツールスキーマとしてプロンプトに埋め込み、それをネイティブパーサが受けます。


7. 編集プロンプトはかなり実務的

エージェントプロンプトの編集指示は、実務的で興味深いです。

write は新規ファイルまたは意図的なファイル全置換に使う。通常の変更は edit を使う。editold は現在のファイルにちょうど一度だけ一致しなければ失敗する。

さらに大きな置換では、[upto] を使ったアンカー付き編集を推奨しています。

For large replacements, prefer anchored old text:
write the first lines, then [upto], then the final lines.

これはローカル LLM のデコード速度と文脈の圧力をよく理解した設計です。

巨大なファイル全体をモデルに再出力させると遅く、ミスも増えます。必要なアンカーを read / search で集め、old/new の狭い差分だけをツールに渡すほうが安定します。

DS4 エージェントは「モデルが賢ければ何でもできる」ではなく、ローカル推論の制約に合わせてワークフローを作っています。


8. DSML パーサは厳密

エージェント側にも DSML パーサがあります。

コメント

/* The model streams raw text tokens. This parser recognizes completed DSML
 * tool stanzas and keeps a copy of the raw stanza for diagnostics. It is
 * deliberately strict after the opening marker ...
 */

パーサの状態は次のように分かれています。

typedef enum {
    AGENT_DSML_SEARCH,
    AGENT_DSML_STRUCTURAL,
    AGENT_DSML_PARAM_VALUE,
    AGENT_DSML_DONE,
    AGENT_DSML_ERROR,
} agent_dsml_state;

開始マーカーを見つけるまではストリーミング検出器がある程度面倒を見ますが、DSML ブロックとして開始した後は厳密にパースします。誤字の回復をパーサ本体に入れすぎないことで、ツール実行の誤爆を避けています。

ツール呼び出しが完成すると、agent_tool_call に名前と引数が入り、ネイティブのツールディスパッチに渡されます。


9. ストリームの可視化

エージェントは生のアシスタントテキストとツール呼び出しをターミナルに表示します。agent_tool_visualizer は、ツール名やパラメータの型に応じて表示を変えます。

例えば、

  • read はパスと行範囲をコンパクトに表示
  • bash のコマンドは目立つ色
  • edit の old/new は diff 風に表示
  • write / edit のコード本体はコードとして扱う

この部分は推論エンジンそのものではありませんが、ネイティブエージェント体験には効きます。ツール呼び出しが隠れた JSON として裏で発生するのではなく、モデルが何をしようとしているかをストリーミング中に見せます。


10. システムプロンプトのリマインダ

長いセッションでは、最初のシステム/ツールプロンプトが文脈の遠い位置に流れていきます。エージェントは一定トークン数ごとにシステムプロンプトのリマインダを再注入します。

#define AGENT_SYSTEM_PROMPT_REMINDER_TOKENS 50000

agent_worker_maybe_append_system_prompt_reminder() は、前回のリマインダから 50k トークン以上進むと、ツールプロンプトと追加のシステム指示を再度トランスクリプトに入れます。

これは長文脈モデルでも実用上重要です。1M の文脈があっても、エージェントのツール構文や編集ルールは定期的に近い位置へ戻したほうが安定します。


11. Web ツールは可視ブラウザ前提

エージェントプロンプトには google_searchvisit_page もあります。実装コメントには、Web サブシステムは Chrome を立ち上げ、エージェント側は権限、ツールディスパッチ、visit_page の上限を扱うとあります。

初回の Web 呼び出しではユーザー権限を求める設計です。これはネイティブエージェントがローカルマシンの外へ出る境界なので、ファイルツールとは扱いが違います。

サーバ互換 API だけではこの種の UI/権限フローを入れるのが難しいですが、ネイティブエージェントならターミナル UI とワーカー状態の中に直接組み込めます。


12. ネイティブエージェントの利点と限界

README が挙げる利点を、実装目線で言い換えると以下です。

利点 実装上の理由
低レイテンシ ソケット/API 境界がなく、ワーカーがセッションを直接持つ
ライブ進捗バー prefill とセッション状態が同一プロセス内
DSML 変換不要 ツールプロンプトとパーサが DSML ネイティブ
KV 不一致が構造的に起きにくい 現在の状態が常にワーカーセッションの真実
セッション切り替えが速い フル KV ペイロードを ~/.ds4/kvcache からロード

一方で、README は ds4-agent を alpha 品質とし、prime time にはまだ作業が必要とも書いています。将来的には、ネイティブエージェントで得た形をもとに、ステートフルなセッションプロトコルを持つサーバ/クライアント分離へ進む可能性が示されています。

これは自然な進化です。OpenAI/Anthropic 互換 API は既存クライアント接続に強い。一方、ネイティブエージェントは DS4 に最適化した UX と状態モデルを試せる。この実験結果をステートフルなプロトコルに戻せれば、両者の良い部分を合わせられます。


13. この記事の要点

ds4-agent は、DwarfStar の「推論エンジン + 専用 GGUF + エージェント検証」という思想の、C に相当する部分です。

  1. エンジンと同じプロセス内でライブセッションを操作する
  2. セッション保存はオンディスク KV キャッシュそのもの
  3. ツール呼び出しは DSML ネイティブで、JSON 互換層を通らない
  4. ツールプロンプトはローカルコーディングのワークフローに強く寄せている
  5. /save, /list, /switch, /strip で長時間のローカルセッションを扱う
  6. システムプロンプトのリマインダやアンカー付き編集など、ローカル推論の制約に合わせた工夫がある

次回は最終回として、DwarfStar の周辺実験機構をまとめます。directional steering、MTP speculative decoding、ds4-evalds4-bench、自前データ構造など、連載本編に入りきらなかった技術的な見どころを拾います。


本記事は クイックイタレート株式会社 のローカル LLM 研究の一環として、
公開リポジトリ antirez/ds4 のコードを読み解いたものです。行番号・定数・ベンチ値は閲覧コミット ba00a8a(2026-05-30)/README 取得日 2026-06-01 時点のものです。ds4-agent は alpha、エンジン本体は beta 品質で活発に変化するため、引用箇所は各自で最新の README / ソースに当たって再確認してください。


クイックイタレート株式会社
IoT / 電力監視 / AI / 衛星・無線通信 / システムインテグレーション/
ローカル LLM・エージェント基盤に関するお問い合わせはお気軽にどうぞ。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?