Sema について
Sema は Scheme 系の Lisp で、LLM エージェントを言語のプリミティブとして扱い、バイトコード VM にコンパイルして単一のバイナリとして配布します。LLM 呼び出しをスクリプトで記述する開発者向けに、リトライやキャッシュ、予算管理をランタイム側で処理します。
主な機能
- 01プロンプト、会話、ツールを第一級のデータ型として扱う
- 02複数の LLM プロバイダーの自動設定
- 03レスポンスキャッシュ、フォールバックチェーン、レート制限、リトライ
- 04予算追跡と OpenTelemetry による自動トレース
- 05フォーマッター、LSP、DAP、MCP サーバーを内蔵
活用シーン
- 01ファイル操作ツールを備えたコーディングエージェントのスクリプト作成
- 02自由テキストからの構造化データ抽出
- 03コマンドラインでのコスト上限付きバッチ LLM 実行
MCP 対応
sema mcp コマンドは Claude Desktop、Cursor、Claude Code などの LLM クライアント向けに MCP サーバーを起動します。Sema コードのコンパイル、フォーマット、評価、ビルドを提供し、deftool で定義した Lisp ツールも呼び出せます。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
このサーバーのパッケージやリモートエンドポイントはまだ取得できていません。プロジェクトの README の手順に従ってください。
ツール
ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。
詳細
Sema
LLM エージェントが SDK ではなく言語プリミティブである Lisp — 高速なバイトコード VM にコンパイルされ、単一のバイナリとして配布されます。
エージェントのループを書き直すのはもうやめましょう。 どの LLM スクリプトにも、リトライ、キャッシュ、コスト上限、レート制限、ツールのディスパッチ、会話状態といった同じ足場が増えていきます。Sema はその足場をランタイムにします。スクリプトはアイデアの大きさのまま、単一のバイナリとして配布でき、コーディングエージェントもすでにこの言語を扱えます。
Sema は Scheme 風の Lisp で、プロンプトは S 式、会話は永続データ構造、LLM 呼び出しは単なる評価の一形式です。Clojure 風のキーワード(:foo)、マップリテラル({:key val})、ベクターリテラル([1 2 3])を備えています。
どのような見た目か
ファイルツール、安全性チェック、予算追跡を備えたコーディングエージェントを、約 40 行で記述できます。
;; Define tools the LLM can call
(deftool read-file
"Read a file's contents"
{:path {:type :string :description "File path"}}
(lambda (path)
(if (file/exists? path) (file/read path) "File not found")))
(deftool edit-file
"Replace text in a file"
{:path {:type :string} :old {:type :string} :new {:type :string}}
(lambda (path old new)
(file/write path (string/replace (file/read path) old new))
"Done"))
(deftool run-command
"Run a shell command"
{:command {:type :string :description "Shell command to run"}}
(lambda (command) (:stdout (shell "sh" "-c" command))))
;; Create an agent with tools, system prompt, and spending limit
(defagent coder
{:system (format "You are a coding assistant. Working directory: ~a" (sys/cwd))
:tools [read-file edit-file run-command]
:max-turns 20}) ; no :model → uses the configured default provider
;; Run it — budget is scoped, automatically restored after the block
(llm/with-budget {:max-cost-usd 0.50} (lambda ()
(define result (agent/run coder "Add error handling to src/main.rs"))
(println (:response result))
(println (format "Cost: $~a" (:spent (llm/budget-remaining))))))
主な機能
;; Simple completion
(llm/complete "Explain monads in one sentence")
;; Structured data extraction — returns a map, not a string
(llm/extract
{:vendor {:type :string} :amount {:type :number} :date {:type :string}}
"Bought coffee for $4.50 at Blue Bottle on Jan 15")
;; => {:amount 4.5 :date "2025-01-15" :vendor "Blue Bottle"}
;; Classification
(llm/classify (list :positive :negative :neutral) "This product is amazing!")
;; => :positive
;; Multi-turn conversations as immutable data
(define conv (conversation/new {:model "claude-haiku-4-5-20251001"}))
(define conv (conversation/say conv "The secret number is 7"))
(define conv (conversation/say conv "What's the secret number?"))
(conversation/last-reply conv) ;; => "The secret number is 7."
;; Streaming
(llm/stream "Tell me a story" {:max-tokens 500})
;; Batch — all prompts sent concurrently
(llm/batch (list "Translate 'hello' to French"
"Translate 'hello' to Spanish"
"Translate 'hello' to German"))
;; Vision — extract structured data from images
(llm/extract-from-image
{:text :string :background_color :string}
"assets/logo.png")
;; => {:background_color "white" :text "Sema"}
;; Multi-modal chat — send images in messages
(define img (file/read-bytes "photo.jpg"))
(llm/chat (list (message/with-image :user "Describe this image." img)))
;; Cost tracking
(llm/set-budget 1.00)
(llm/budget-remaining) ;; => {:limit 1.0 :spent 0.05 :remaining 0.95}
;; Response caching — avoid duplicate API calls during development
(llm/with-cache (lambda ()
(llm/complete "Explain monads")))
;; Cassettes — record real responses once, replay them in CI (no keys, no network)
(llm/with-cassette "fixtures/run.jsonl" {:mode :auto} (lambda ()
(llm/complete "Explain monads")))
;; Fallback chains — automatic provider failover
(llm/with-fallback [:anthropic :openai :groq]
(lambda () (llm/complete "Hello")))
;; In-memory vector store for semantic search (RAG)
(vector-store/create "docs")
(vector-store/add "docs" "id" (llm/embed "text") {:source "file.txt"})
(vector-store/search "docs" (llm/embed "query") 5)
;; Cross-encoder reranking — the retrieve-many → rerank-to-a-few RAG move
(llm/rerank "how do I read a file?"
["file/read returns a string" "http/get fetches a URL"]
{:top-k 3})
;; => ({:index 0 :score 0.98 :document "file/read returns a string"} ...)
;; Text chunking for LLM pipelines
(text/chunk long-document {:size 500 :overlap 100})
;; Prompt templates
(prompt/render "Hello {{name}}" {:name "Alice"})
; => "Hello Alice"
;; Persistent key-value store
(kv/open "cache" "cache.json")
(kv/set "cache" "key" {:data "value"})
(kv/get "cache" "key")
対応プロバイダー
すべてのプロバイダーは環境変数から自動設定されます。API キーを設定するだけで使えます。
| プロバイダー | チャット | ストリーム | ツール | 埋め込み | ビジョン |
|---|---|---|---|---|---|
| Anthropic | ✅ | ✅ | ✅ | — | ✅ |
| OpenAI | ✅ | ✅ | ✅ | ✅ | ✅ |
| Google Gemini | ✅ | ✅ | ✅ | — | ✅ |
| Ollama | ✅ | ✅ | ✅ | — | ✅ |
| Groq | ✅ | ✅ | ✅ | — | — |
| xAI | ✅ | ✅ | ✅ | — | — |
| Mistral | ✅ | ✅ | ✅ | — | — |
| Moonshot | ✅ | ✅ | ✅ | — | — |
| Jina | — | — | — | ✅ | — |
| Voyage | — | — | — | ✅ | — |
| Cohere | — | — | — | ✅ | — |
| OpenAI 互換の任意のプロバイダー | ✅ | ✅ | ✅ | — | ✅ |
| カスタム(Lisp) | ✅ | — | ✅ | — | — |
本格的な Lisp でもあります
数百の組み込み関数、末尾呼び出し最適化、マクロ、モジュール、エラー処理を備えています。おもちゃではありません。
;; Closures, higher-order functions, TCO
(define (fibonacci n)
(let loop ((i 0) (a 0) (b 1))
(if (= i n) a (loop (+ i 1) b (+ a b)))))
(fibonacci 50) ;; => 12586269025
;; Full R7RS numeric tower — bignums, exact rationals, complex numbers
(expt 2 100) ;; => 1267650600228229401496703205376
(+ 1/2 1/3) ;; => 5/6
(sqrt -1) ;; => 0+1i
;; Maps, keywords-as-functions, f-strings
(define person {:name "Ada" :age 36 :langs ["Lisp" "Rust"]})
(:name person) ;; => "Ada"
(println f"${(:name person)} knows ${(length (:langs person))} languages")
;; Destructuring
(let (({:keys [name age]} person))
(println f"${name} is ${age}"))
;; Pattern matching with guards
(define (classify n)
(match n
(x when (> x 100) "big")
(x when (> x 0) "small")
(_ "non-positive")))
;; Functional pipelines
(->> (range 1 100)
(filter even?)
(map #(* % %))
(take 5))
;; => (4 16 36 64 100)
;; Nested data access
(define config {:db {:host "localhost" :port 5432}})
(get-in config [:db :host]) ;; => "localhost"
;; Macros
(defmacro unless (test . body)
`(if ,test nil (begin ,@body)))
;; Modules
(module utils (export square)
(define (square x) (* x x)))
;; HTTP, JSON, regex, file I/O, crypto, CSV, datetime...
(define data (json/decode (http/get "https://api.example.com/data")))
📖 言語リファレンス、標準ライブラリのドキュメント、その他のサンプルは sema-lang.com/docs をご覧ください。
今すぐ試す
sema.run — 20 以上のサンプルプログラムを備えた、ブラウザー上で動作するプレイグラウンドです。 インストールは不要です。すべて WebAssembly 上で実行されます。
コーディングエージェントに Sema を一行で教える
Sema は新しいため、エージェントはまだ Sema を知りません。1 つのコマンドで解決できます。エージェント向けの要点をまとめたシートをリポジトリの AGENTS.md に追記し、CLAUDE.md から参照するようにします。
curl -fsSL https://sema-lang.com/docs/for-agents.md >> AGENTS.md
ln -s AGENTS.md CLAUDE.md # Claude Code, Cursor, etc. read this
for-agents.md は、Lisp をすでに知っている LLM 向けの簡潔な実用ガイドです。生成コードの誤りにつながりやすいルールを解説し、すべてのドキュメントページを一覧にした機械可読インデックス /llms.txt へのリンクもあります。マニュアル全体を読み込む代わりに、必要なページだけ(たとえば /docs/llm/tools-agents.md)を取得できます。すべてのドキュメント URL は生の Markdown も提供しています。sema-lang.com/docs/... のリンクに .md を追加すると、ソースを取得できます。
インストール
ビルド済みバイナリをインストールします(Rust は不要です)。
# macOS / Linux
curl -fsSL https://sema-lang.com/install.sh | sh
# Windows (PowerShell)
powershell -ExecutionPolicy ByPass -c "irm https://github.com/sema-lisp/sema/releases/latest/download/sema-lang-installer.ps1 | iex"
# Homebrew (macOS / Linux)
brew install helgesverre/tap/sema-lang
または、crates.io からインストールします。
cargo install sema-lang
または、ソースからビルドします。
git clone https://github.com/sema-lisp/sema
cd sema && cargo build --release
# Binary at target/release/sema
最適化されたバイナリが必要なローカル開発では、jake release-fast または cargo build --profile release-fast を使用します。バイナリは target/release-fast/sema にあります。このプロファイルでは、インクリメンタルコンパイルと並列コード生成を使用し、クレート間 LTO は行いません。パフォーマンス測定や配布用ビルドには --release を使用してください。ビルド時間と実行時のトレードオフについては、ビルドプロファイルの測定結果を参照してください。
sema # REPL (with tab completion)
sema script.sema # Run a file
sema -e '(+ 1 2)' # Evaluate expression
sema --no-llm script.sema # Run without LLM (faster startup)
sema build app.sema -o myapp # Build standalone executable
./myapp # Run without sema installed
シェル補完
使用するシェル用のタブ補完スクリプトを生成します。
# Zsh (macOS / Linux)
mkdir -p ~/.zsh/completions
sema completions zsh > ~/.zsh/completions/_sema
# Bash
mkdir -p ~/.local/share/bash-completion/completions
sema completions bash > ~/.local/share/bash-completion/completions/sema
# Fish
sema completions fish > ~/.config/fish/completions/sema.fish
📖 各シェルの詳しいセットアップ手順:sema-lang.com/docs/shell-completions
📖 CLI の全リファレンス、フラグ、REPL コマンド:sema-lang.com/docs/cli
エディターサポート
各エディタープラグインは、sema-lisp 組織の個別のリポジトリにあります。
| エディター | リポジトリ | インストール |
|---|---|---|
| VS Code | vscode-sema | ext install sema-lang.sema-lang |
| Zed | zed-sema | Extensions → Sema を検索 |
| IntelliJ | intellij-sema | JetBrains Marketplace → Sema |
| Neovim | sema.nvim | { "sema-lisp/sema.nvim" } |
| Vim | sema.vim | Plug 'sema-lisp/sema.vim' |
| Emacs | emacs-sema | MELPA → sema-mode |
| Helix | helix-sema | clone + ./install.sh |
| Sublime Text | sublime-sema | Package Control → Sema |
すべてのプラグインが構文ハイライトを提供します。VS Code、Zed、IntelliJ、Neovim、Emacs、Helix、Sublime では、組み込みの言語サーバー(sema lsp)も連携します。また、複数のエディター(VS Code、Zed、IntelliJ、Neovim、Helix)ではデバッグ(sema dap)も利用でき、その一部ではMCP サーバー(sema mcp)も登録されます。Zed、Helix、Neovim は共通の tree-sitter-sema 文法でハイライトし、その他のエディターはそれぞれ独自の文法を同梱しています。
📖 詳しいインストール手順とエディターごとの機能一覧:sema-lang.com/docs/editors
ノートブック
Sema には、ブラウザー UI を備えた Jupyter に着想を得たノートブックインターフェースがあります。
sema notebook new my-notebook.sema-nb # Create a notebook
sema notebook serve my-notebook.sema-nb # Open in browser (localhost:8888)
sema notebook run my-notebook.sema-nb # Run all cells headlessly
sema notebook export my-notebook.sema-nb # Export to Markdown
セルは永続的な環境を共有するため、前のセルで定義した内容を後のセルから参照できます。ノートブックは .sema-nb JSON ファイルとして保存されます。
📖 ノートブックの詳しいドキュメント:sema-lang.com/docs/notebook
言語ツール
プラグインを組み合わせる必要はありません。完全なツールチェーンが同梱されています。
sema fmt script.sema # Canonical code formatter
sema lsp # Language Server (completions, hover, go-to-def, rename)
sema dap # Debug Adapter (breakpoints, stepping, variable inspection)
sema mcp # Model Context Protocol server for LLM clients
MCP サーバーを使うと、LLM クライアント(Claude Desktop、Cursor、Claude Code)が、Sema コードのコンパイル、フォーマット、評価、ビルドに加え、独自の deftool Lisp ツールの呼び出しも、直接お使いの環境で行えます。
サンプルプログラム
examples/ ディレクトリには、50 以上のプログラムがあります。
| サンプル | 概要 |
|---|---|
coding-agent.sema | ファイル編集、検索、シェルツールを備えた完全なコーディングエージェント |
review.sema | Git の差分をレビューする AI コードレビュアー |
commit-msg.sema | ステージングされた変更から Conventional Commit メッセージを生成 |
summarize.sema | ファイルまたはパイプ入力を要約 |
game-of-life.sema | コンウェイのライフゲーム |
brainfuck.sema | Brainfuck インタープリター |
mandelbrot.sema | ASCII マンデルブロ集合 |
json-api.sema | JSON API の取得と処理 |
test-vision.sema | ビジョン抽出とマルチモーダルチャットのテスト |
test-extract.sema | 構造化抽出と分類 |
test-batch.sema | LLM のバッチ/並列補完 |
test-pipeline.sema | キャッシュ、予算、レート制限、再試行、フォールバックチェーン |
test-text-tools.sema | テキストの分割、プロンプトテンプレート、ドキュメントの抽象化 |
test-vector-store.sema | 類似性検索に対応したインメモリのベクトルストア |
test-kv-store.sema | JSON ベースの永続キーバリューストア |
expr-evaluator.sema | タグ付きベクトルに対する match を使用したミニ計算機 |
shape-geometry.sema | マップのパターンマッチングによる図形の面積/周長 |
http-router.sema | ネストしたマップとガードに対する match を使用した HTTP ルーター |
destructuring.sema | 分割代入の包括的な紹介(ベクトル、マップ、ラムダ) |
demo.sema-nb | 対話型ノートブックのデモ(sema notebook serve で実行) |
Sema を選ぶ理由
ひと言で言えば、LangChain もプロバイダー SDK もエージェントフレームワークも接着用スクリプトも不要です。エージェントループ、再試行、キャッシュ、予算管理、トレース、ツールのディスパッチは言語ランタイムに組み込まれており、全体が 1 つのバイナリなので、scp でサーバーに転送できます。
- LLM を言語のプリミティブとして扱えます — プロンプト、メッセージ、会話、ツール、エージェントは、文字列テンプレートに後付けするものではなく、第一級のデータ型です
- マルチプロバイダー対応 — Anthropic、OpenAI、Gemini、Ollama、OpenAI 互換の任意のエンドポイントを切り替えて使えるほか、Sema で独自のプロバイダーを定義できます
- パイプラインですぐに使えます — レスポンスキャッシュ、フォールバックチェーン、レート制限、バックオフ付き再試行、テキストのチャンク分割、プロンプトテンプレート、ベクトルストア、永続 KV ストアを備えています
- コストを把握できます — 価格スナップショット(models.dev)を同梱した予算追跡機能を内蔵し、リリースごとに更新しています
- 可観測性を備えています — LLM/エージェントの実行はすべて、OpenTelemetry(GenAI セマンティック規約)で自動トレースされます。トークン数、コスト、レイテンシー、
invoke_agent → chat → execute_toolの完全なツリーを記録し、Jaeger、Grafana、Datadog、Langfuse、Arize Phoenix などにエクスポートできます。手動の計装は不要で、デフォルトでは無効です - 実用的な Lisp — クロージャー、TCO、マクロ、モジュール、エラー処理、HTTP、ファイル I/O、正規表現、JSON、充実した標準ライブラリーを備えています
- スタンドアロン実行ファイル —
sema buildは、トレース機能付きのインポートとバンドル済みアセットを含む自己完結型バイナリにプログラムをコンパイルします - 組み込み可能 — ビルダー API を備えた Rust クレート、または
@sema-lang/semaを使い、WebAssembly 経由で JS 上で Sema をクライアントサイド実行できます - 完全なツールチェーン — フォーマッター、言語サーバー(LSP)、デバッガー(DAP)、LLM クライアント向け MCP サーバーをすべて内蔵しています
- パッケージマネージャー —
sema pkgは git またはライブレジストリ pkg.sema-lang.com から依存関係を取得します。sema.lockでバージョンを固定し、再現可能なインストールを実現します - 開発者にやさしい設計 — タブ補完機能付き REPL、ヒント付きの構造化エラーメッセージ、50 個以上のサンプルプログラムを備えています
Sema を選ばない理由
- 継続(
call/cc)や完全に衛生的なマクロ(syntax-rules)はありません — 変数捕捉を防ぐための自動 gensym(foo#)を備えています - シングルスレッドです —
Rcベースで、値をスレッド間で共有できません - JIT はありません — バイトコードコンパイラーとスタックベースの VM を使用し、ネイティブコードを生成しません
- 新しい言語です — 堅実ですが、大規模環境での実績はまだありません
アーキテクチャ
crates/
sema-core/ NaN-boxed Value type, errors, environment
sema-reader/ Lexer and s-expression parser
sema-vm/ Bytecode compiler and virtual machine
sema-eval/ Trampoline-based evaluator, special forms, modules
sema-stdlib/ Built-in functions across many modules
sema-io/ Process-wide async I/O pool (tokio) behind the core seam
sema-llm/ LLM provider trait + multi-provider clients
sema-workflow/ Dynamic-workflow runtime — journaled runs, bounded fan-out, --resume
sema-otel/ OpenTelemetry tracing (GenAI semantic conventions)
sema-docs/ Canonical builtin docs (powers LSP hover + REPL apropos)
sema-lsp/ Language Server Protocol implementation
sema-dap/ Debug Adapter Protocol server
sema-fmt/ Source code formatter
sema-mcp/ Model Context Protocol server
sema-notebook/ Jupyter-inspired notebook interface with browser UI
sema-wasm/ WebAssembly build for sema.run playground
sema/ CLI binary: REPL + file runner + standalone builder
ライセンス
MIT — LICENSE をご覧ください。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。