Language Model
Generate text, structured objects, and streaming responses against a provider-agnostic model, with usage and finish-reason metadata.
Effect’s AI modules provide a provider-agnostic interface for large language
models. You describe what you want — generate text, decode a structured object,
stream a response, call tools — against a single LanguageModel
service. Which provider answers (OpenAI, Anthropic, OpenRouter, …) is a
Layer you wire up once at the edge of your application.
Because everything is an Effect, AI calls compose with the rest of the
ecosystem: typed errors, retries and fallbacks via scheduling and
ExecutionPlan, streaming, observability spans,
and dependency injection through services and layers.
import { Effect } from "effect"import { LanguageModel } from "effect/unstable/ai"
// The program depends only on the abstract LanguageModel service —// it knows nothing about which provider will run it.const program = Effect.gen(function*() { const response = yield* LanguageModel.generateText({ prompt: "Explain what an Effect is in one sentence." })
return response.text})The core API lives in effect/unstable/ai. Provider implementations ship as
separate packages — @effect/ai-openai, @effect/ai-anthropic,
@effect/ai-openrouter — each exposing a client Layer and a model(...)
helper that supplies a concrete LanguageModel.
Language Model
Generate text, structured objects, and streaming responses against a provider-agnostic model, with usage and finish-reason metadata.
Tools
Define tools and toolkits the model can call. The framework resolves parameters, runs your handlers, and feeds results back to the model.
Chat
Stateful chat sessions that track conversation history automatically — the foundation for assistants and agentic loops.
There are three layers to an AI feature in Effect:
LanguageModel, Tool, Toolkit, and Chat modules. No provider details.Layer from a provider package (e.g.
OpenAiLanguageModel.model("gpt-5.2")) that provides a concrete
LanguageModel plus Model.ProviderName / Model.ModelName metadata.Layer holding credentials and an
HttpClient (e.g. OpenAiClient.layerConfig({ ... })),
which the model Layer depends on.Keeping these separate means you can swap providers, run the same program against
a fake model in tests, or try several providers in sequence with an
ExecutionPlan — all without touching your business logic.