Sente(先手)— teai.ioのコーディングエージェントCLIを作り、
Claude Code・Codexと比べた
teai.io に、ターミナルで動くコーディングエージェント Sente(先手) を追加しました。 1行で入り、teai.io の全モデルをエージェントとして使えます。 作るにあたって Claude Code・Codex と同じタスクで比較したところ、 「どのモデルが賢いか」ではなく「teai 経由でツールが崩れず最後まで打ち切れるか」で はっきり差が出ました。その実測と、精度を磨いた過程を残します。
- Sente は
curl -fsSL https://teai.io/te | shで1行で入る。teai 経由で崩れず動くのは Sente だけ(OpenAI互換ネイティブだから)。 te maxで Kimi K3(2.8T・1M)に一言で切替。日常は安価な既定モデル、勝負どころは K3。- コーディング規律の注入で「読んでから書く」は実証的に改善。監査の"質"はモデルの地力に依存し、そこは
te maxで上げる。
使い方
curl -fsSL https://teai.io/te | sh
te # カレントディレクトリでエージェント起動
te run "このリポを説明して"
te max run "..." # 最高性能モード = Kimi K3(2.8T・1M context)
te -m teai/<model> # モデル切替(te models で一覧)
Sente は OpenCode をベースにした薄いランチャーで、フォークはしていません。
OPENCODE_CONFIG を teai.io 生成の設定に向けるだけなので、OpenCode 本体の進化にそのまま乗れます。
モデルカタログ(現在95+)は起動ごとに /te/config から自動同期されます。
なぜ「先手」か
teai.io は「手AI」。その「手」を継いで、囲碁の 先手(せんて) から名付けました。
あなたより先に、エージェントが手を動かす。"Always keep sente" — 主導権を手放さない、という意味も込めています。
コマンドは短く te(sente エイリアスも入ります)。
最高性能モード:te max = Kimi K3
当初 Sente の既定は安定重視で glm-5.2 にしていました。理由は、Moonshot の主力 Kimi K3(2.8T・1Mコンテキスト)を OpenCode 経由でストリーミングすると、以前は 応答が返らずハングしていたためです。ところがその後 teai 側のストリーミング/フォールバック処理が 改善され、今は Kimi K3 が完全に動きます — 実測で確認しました:
- SSE ストリーミング:
role → content → stop → [DONE]正常終了 - ストリーミング + tool calling:
tool_callsに引数が正しく乗りfinish_reason:tool_calls - Sente 実起動(OpenCode): ファイル作成タスクを K3 が完遂(
Write K3.txt → Wrote file successfully)
そこで te max を追加しました。既定のコスト効率(glm-5.2)は保ちつつ、
一言で最高性能に切り替えられます:
te max run "この関数をリファクタして、テストも書いて"
te max # 対話モードを K3 でte(glm-5.2)、勝負どころは te max(K3)という使い分けです。
Sente 対 Claude Code 対 Codex — 同じ盤で比べる
公平にするため3クライアントとも teai バックエンド経由に揃え、自社コード
(Rust axum・2.5万行の http.rs)のセキュリティ監査を実際にやらせました。
「.unwrap() のうち攻撃者入力で panic しうる1件を見つけて FINDING.md に書け」という実タスクです。
| クライアント | teai経由の挙動 | 結果 |
|---|---|---|
| Sente(OpenCode) | OpenAI互換をそのまま送る。変換ゼロ | 崩れず完走 |
| Claude Code | Anthropic tool_use を teai が変換 | kimi-k3で崩壊 |
| Codex | 独自function-call+サンドボックス | シェル崩壊 |
Claude Code は teai/kimi-k3 で <ctrl46> という制御トークンをテキスト出力してツールが発火せず、
Codex は生成したシェルコマンドが壊れて execvp() failed で即死しました。
いずれも「クライアントが悪い」のではなく、各社のツール様式(Anthropic の tool_use、Codex 独自形式)を
teai の OpenAI互換変換層が完全再現できないために起きます。
<ctrl46> 崩壊は、このベンチ実施後に
teai 側で原因が特定され修正されました(真因は tool_choice の未伝播で、Claude Code や Kimi K3 の
問題ではありません)。本番で再検証したところ、Claude Code + teai/kimi-k3 は正常にファイルを生成し、
<ctrl46> は再現しませんでした。上のベンチはあくまでその時点の記録です。
なお「Sente は変換層ゼロだから構造的に崩れどころが少ない」という利点自体は変わりません。
正直な話:指摘の"質"はモデルの天井に当たる
ただし完走 = 良い監査、ではありません。統一モデル glm-5.2 では、3クライアントとも
テストコード内の .unwrap() を脆弱性と誤認しました(#[test] の中は攻撃者入力が届かないので脆弱性ではない)。
これはクライアントの差ではなく、モデルの監査能力の限界です。全 FINDING を実コードと照合して確認しました。
磨く:抽象ルールより「機械的手順」
そこで Sente にコーディング規律を組み込みました。起動ごとに
~/.config/teai/sente-rules.md を書き出し、設定の instructions で全セッションに注入します。
調査(AGENTS.md ベストプラクティス)でも「抽象原則より、機械的に従える具体手順の方が効く」と一致したので、
判定を手順に落としました:
- 読んでから書く — 実コードをツールで開く前に、ファイル作成も指摘も禁止。行番号やAPIの憶測禁止。
- テストコード除外を機械化 — 「直上のマーカーが
#[test]/mod testsならスキップ」「assert_eq!に囲まれ・ファイル後半にある = ほぼテスト」「ハンドラ(Json/HeaderMap/impl IntoResponse)の行を優先」。 - 必ず成果物を出す — 探索で終わらず、依頼された成果物を出してからターンを終える。
- 大きいファイルは grep で絞ってから部分読み — 2.5万行を頭から読まない(トークン節約)。
効果は割れました。規律注入前は「読む前に憶測で行番号を書く」失敗がありましたが、注入後は
実コードを読んでから、実在する .unwrap() の行を指してFINDINGを書く挙動に変わりました
— read-before-write は実証的に直りました。
一方で、テストコード除外だけは機械的手順を書いても直りませんでした。
「直上が #[test] ならスキップ」「ファイル後半で assert_eq! に囲まれていればテスト」と
明示しても、glm-5.2 は末尾のテストモジュール内の .unwrap() を選び続けます。
これはルールの書き方の問題ではなく、モデルの判断力の天井です。
te -m で切替可能)。
おまけ:比較の準備中に本番バグを1つ直した
この比較の下ごしらえ中に、teai の /v1/chat/completions が role:"tool" のメッセージと
アシスタントの tool_calls を捨てていたバグを発見・修正しました(本番デプロイ済み)。
これはツールを往復させる全エージェントのループを壊す不具合で、Sente に限らず効きます。
まとめ
- Sente は teai.io の公式コーディングエージェントCLI。
curl -fsSL https://teai.io/te | shで1行で入る。 - teai バックエンド経由で崩れず動くのは Sente(構造的に OpenAI互換ネイティブだから)。
- 規律注入で「読んでから書く/必ず成果物を出す」は実証的に改善。監査の質はモデル選択で上げる。