Harder Stronger Better Faster Agentic Coding
Cloudflare Workers Tech Talks in Kyoto #2 - connpass
2026/7/8
枠: 15min
id:Windymelt @windymelt
タイマーをスタート
プレゼンタイマー
おしながき
Agentがホームディレクトリを破壊する!! セッションを盗む!! killallする!!
生成したコードがポンコツで中途半端に動かれても困るわよ
いったいどうする!?
撮影・ツイート OK https://scrapbox.io/files/6a4e1a05be32792658d162f6.png
いいコマがあったら撮影してツイートしよう
誰
windymelt.icon
@windymelt / id:Windymelt ともうします
はてな在籍
https://www.3qe.us
好きなCloudflareの機能: Zero Trust
欲しいCloudflareの機能: プロジェクト分け
最近作ったもの: Inertia.scala
緊急アンケート
型付けてる?
つけている
つけていない
部分的にそう
Agentは便利だが危険でもある
Agentic Coding、やってるカナ?😅
適切に利用することで高い生産性が得られる
プロダクト自体にもAgentが組込まれている時代
Agentが思考してプロダクト上の操作を行う
マシンで直接Agentが(LLMではない)動作することは潜在的なリスクをともなう
ホームディレクトリを破壊される
Claude Code くんのホームディレクトリ破壊を AppArmor で阻止する - Lambdaカクテル
コンテキストの不十分な理解に基いて不可逆な操作を実行する
直近の例: ローカルサーバを止めようとしてkillallで同名のプロセスを薙ぎ払う(殺人エージェント)
機微なデータを奪取される
シェルを起動した上で処理系にアクセスしてセッションを奪ったり任意のクエリを発行される
LLMの性能が日に日に向上しているため、ハルシネーションにもとづいた誤動作というモードは減ってきたが、他方でその高い能力によってより破壊的な行動もできるようになっている
プロダクトに組込まれたエージェントのプロンプトインジェクションが成功すると致命的な打撃を加えうる
権限をいかに管理するか?が重要な課題として浮上した
Agentの2つの側面
コードを生成する
LLMの能力を用いて、動作するコードを出力する
リスク要因: そのコードは権限通り正しく動作するのか?
リスクが具現化すると?: 危険なコードを実行される
コードを実行する
LLMが生成したコードを用いて、シェルや処理系を通じて現実世界に干渉する
リスク要因: その環境は権限通り適切に閉じているか?
リスクが具現化すると?: 危険なコードが外部や内部に影響を及ぼす
最小権限の原則
コンピュータセキュリティの一般的な原則
必要なときに、必要な範囲と強さの権限のみを、またそのときに限り持つべきである
Agentにも最小権限の原則を適用する必要がある
Agentではどうか
デフォルトで様々な機能の実行が容認されている
fileのreadなど
Claude Codeの場合はauto modeにするとさらに緩和される
また、いちどシェルへのアクセスを容認した場合、安全装置はほぼ無効化されたも同然である
文字通りすべてが可能になる
弾薬が装填されてる状態
この状態でハルシネーションすると破滅が起こる
Agentの2つの側面(再掲)
コードを生成する
ここで最小権限の原則を適用するには?
コードを実行する
ここで最小権限の原則を適用するには?
鍵となる技術
静的型付け
VM
静的型付け
プログラムに静的に型がつくということは、どのコードが何を呼び出すかがあらかじめわかっているということ
特定の危険なメソッドの呼び出しを禁止することができるようになる
シェルの実行
ネットワーク
ファイルの操作
その他の不可逆な操作
もちろん、evalも強制型キャストも禁止だぜ
シートベルト無しで爆走している状態
危険な呼び出しを検知したら型検査を倒してコンパイルに失敗させれば実行もできないので、安全
VM
仮想マシン
マシンの内容を見られたり破壊されたりすると困るのであれば、マシンごと無くせばよい
コードの実行環境からはOSがそのままあるように見えているが、どれだけ暴れても何も破壊できない
Agentの2つの側面(再再掲)
コードを生成する
静的型付けによって、危険なコードを生成できなくする
コードを実行する
VMに隔離して実行することによって、危険なコードが実行されたときの被害を軽減する
どうやって???
(ここまでで5分)
鍵となる技術 1/2: 安全なコードを生成する
Cloudflare Workers AI
割愛
Scala 3: Capture Checking / Safe Mode
2026年7月時点ではExperimental
Cloudflare Containers
2026年4月にGA
Scala 3
JVM系の汎用言語
強い型システムと関数型プログラミング能力が特徴
命令的にも書ける
code:scala
@main def run() =
val xs = List(1, 2, 3)
println(xs.flatMap(n => List(n, 10*n + n)))
val sb = StringBuilder()
sb ++= "Harder"
sb ++= "Stronger"
sb ++= "Better"
sb ++= "Faster"
println(sb.toString())
code:sh
% scala-cli code.scala
List(1, 11, 2, 22, 3, 33)
HarderStrongerBetterFaster
Scala 3: Capture Checking
あるスコープに入っていい参照と出ていっていい参照とを制約するための機構(コンパイラオプション)
Capture: ある値が別の参照を内部に持っていること
val us = List(user1, user2)
usはuser1とuser2とをcaptureしている
Pure: 何もCaptureしていないこと
val n = 42
なにもcaptureしない
非常に汎用的な仕組みなので、なんと権限の強制にも使える
opt-inなのでちょっとずつ武装できる
TypeScriptが漸近的に型を付けるのと同じ感じ
scala/Capture Checking
Capture Checkingで保証できるもの
あるスコープから出るときに、かならず何かを捨てなければならない(参照を持ち出すことを禁じる)
パスワードなどの機微な情報
トランザクションハンドル
はてなのゲスト名札!!!
うっかり混ざったら大事故になるモノを正確に隔離する
DBレコードを雑に渡したらフロントエンドにユーザのヤバデータが渡るみたいな事故を防ぐ
cf. React Taint API
引数は「かならず何かを持参しなければならない」機構
Capture Checking 例
Scalaに不慣れでも心の目で見てくれ
code:scala
// experimentalなので今はこのimportが必要
import language.experimental.captureChecking
// 色々なグッズをimportしてくる
import caps.*
(座学)コンテキスト
コンテキスト: 自動的に引数を渡してくれる便利な仕組み
code:scala
// CSV/TSVシリアライザ
case class Format(sep: String)
def row(cells: ListString)(using fmt: Format): String =
cells.mkString(fmt.sep) // ^^^^^^^^^^^^^^^^^
def table(rows: List[ListString])(using Format): String =
// ^^^^^^^^^^^^
// using Format は型だけの宣言。row に自動転送される
rows.map(row).mkString("\n")
コンテキスト
code:scala
val data = List(
List("id", "name"),
List("1", "Alice"),
List("2", "Bob")
)
{
// givenはコンテキストを供給する
given Format = Format(",")
table(data) // id,name\n1,Alice\n2,Bob
}
{
given Format = Format("\t")
table(data) // id\tname\n1\tAlice\n2\tBob
}
Capture Checking 例
code:scala
// objectはシングルトンクラスを宣言するキーワード
object SecureContext:
// Scalaはクラス内クラスを宣言できる ここではtraitを宣言する
// sealedキーワードにより他のファイルでは継承不可能になる(このファイルで子クラスが閉じる)
// SharedCapabilityを継承することで、「追跡対象である」ことを宣言する
sealed trait SecureZone extends SharedCapability
// SecureZoneの唯一のインスタンスを定義する
// privateなのでここでしか呼び出せない
private object Zone extends SecureZone
// ゾーンを供給してbodyを実行する関数
// A ?-> B は、Aをコンテキストとして受け取り、Bを返すような、純粋な関数
// 純粋とは、この関数の中では何もキャプチャしてはならないということ
def withZoneA(body: (zoneBoundary: SecureZone) ?-> A): A =
body(using Zone)
Capture Checking 例
code:scala
// なんらかのシークレットを表現するクラス
// finalにすることで継承を禁止する
// Secretの作成にSecureZoneを要求することで、ゾーン外での作成を禁じる
final class Secret(value: String)(using SecureContext.SecureZone)
extends SharedCapability:
// ゾーン内であればgetできる
def get(using SecureContext.SecureZone): String = value
// toStringを潰しておく
override final def toString() = "******"
Capture Checking 例
code:scala
// 例: シークレットの消費者
object CloudflareAPI:
// ここには安全装置がないのでシークレットを漏らさないように慎重に実装する
def listBucket(secret: Secret)(using SecureContext.SecureZone) =
// secretの実際の値を使って何かする
val len = secret.get.size
s"returned $len"
Capture Checking 例
code:scala
@main def main =
// ゾーンを開く
// usingで要求される引数(コンテキスト)は自動的に渡される
SecureContext.withZone:
val secret = Secret("this_is_secret!")
println(s"print: $secret")
val apiCall = CloudflareAPI.listBucket(secret)
println(s"apiCall: $apiCall")
Capture Checking 例
Zoneの外にシークレットを持ち出そうとするとコンパイラが拒否する
code:scala
@main def main =
// ゾーンを開く
SecureContext.withZone:
val secret = Secret("this_is_secret!")
return secret
https://scrapbox.io/files/6a4cc2e18eae2d9a231970fc.png
Capture Checking まとめ
ある値が参照を保持していることをCaptureという
Capture Checkingは、既存の型検査に加えて、Captureの制約を課すことができる
Agentがより安全にコードを書ける
より多くの文脈を供給できるから
Scala: Safe Mode
Capture Checkingベースの機能
unsafe type cast / assumingを禁止する
実行時リフレクションを禁止する
Safe Mode自体の解除を禁止する
etc.
Safe Modeでコンパイルしたライブラリしか呼べなくする
Capture Checkingを回避できなくする
既存の安全な道具でしか活動できなくする
Cloudflare Containers
さて、ここからは実行環境の話
Scalaの型システムが便利なのは分かったけど、どこでコンパイルするんだよ
CloudflareはWorkerからコンテナを起動できる
Scala CLIのコンテナイメージが公式にある
動的にコンテナを立てればコンパイルできる!!
Agentが書いたコードをContainersで動的にビルドする
ContainersはWorkersから起動できる
コンテナでコンパイル用のエンドポイントを用意しておけば、HTTP経由でコンパイルさせられる
code:js
const containerId = env.SCALA_COMPILER.idFromName("compiler-1");
const container = env.SCALA_COMPILER.get(containerId);
const resp = await container.fetch("http://container/compile", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ code }),
});
const body = await resp.text();
return new Response(body, {
status: resp.status,
headers: { "Content-Type": "application/json" },
});
ここまでのまとめ
Scalaの型システムで安全なコーディングをある程度強制できる
Cloudflare基盤でコンテナを起動してコンパイルさせることができる
ここまでで10分
鍵となる技術 2/2: VMでコードを実行する
Cloudflare Dynamic Workers
2026年4月にGA
Dynamic Workers
Workersの上から動的にWorkerを起動して任意のJavaScriptをサンドボックス上で実行できる機能
そもそもWorkersは環境が隔離されているが、さらに環境が隔離されて嬉しい
Scala.js
ScalaをJavaScriptに(ECMAScriptに)コンパイルするプラグイン
これでビルドしたコードをDynamic Workersとして起動できる!!!
code:scala
const { js, input } = await request.json<{ js: string; input: string }>();
const result = await executeDynamic(env, js, input);
return new Response(await result.text());
実際にやってみる
「因数分解して」
LLMによるコード生成 5s
ビルド 10s (hot start)
cold startの場合 71s
Dynamic Workerによる実行 50ms
コンテナが暖気されていればまぁまぁ実用範囲
Tradeoff
Scalaの型システムのことを考えるためには、それなりに高級なLLMが必要
へぼいLLMだと御しきれない
Capture Checkig / Safe Modeを利用する場合、さらにLLMに負荷がかかる
しかしながら、LLMの性能もまた上がっているので、リーズナブルになると予想
ちょっと前のGPT-3.5くらいのことを思い出す時間
コンテナがCold startした場合けっこう時間がかかってしまうが、それなりに利用されるようなサービスであれば許容範囲
Workerのサイズ制限があるはず
WASM era is coming
WebAssembly backend - Scala.js
未検証
まとめ
Cloudflare Workers AI、Cloudflare Containers、Cloudflare Dynamic Workersとを組み合わせることで、強い静的型付け言語でコード生成して実行できる
最高便利
Scala 3はAI時代の言語として適応しつつある
っていうまとめの図、作って・・・
🤖しょうがねぇな
https://scrapbox.io/files/6a4e2b8dbe32792658d18b1d.png
おお
本発表
https://scrapbox.io/files/6a4dd503be32792658d06d84.png
DEMO
https://cf-container-scalajs-exercise.windymelt.workers.dev
https://github.com/windymelt/cf-container-scalajs-exercise/tree/main
Appendix: 参考資料
Scala Was an Experiment That Changed Programming - Martin Odersky | The Marco Show : r/scala
Capture Checking