# AI

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`](https://effect.plants.sh/ai/language-model/)
service. *Which* provider answers (OpenAI, Anthropic, OpenRouter, ...) is a
[Layer](https://effect.plants.sh/services-and-layers/) 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](https://effect.plants.sh/scheduling/) and
`ExecutionPlan`, [streaming](https://effect.plants.sh/streaming/), [observability](https://effect.plants.sh/observability/) spans,
and dependency injection through [services and layers](https://effect.plants.sh/services-and-layers/).

```ts
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`.
**Unstable API:** The AI modules live under `effect/unstable/ai`. Unstable modules are production-
usable but may change between minor releases without the usual deprecation cycle.
Import them from `"effect/unstable/ai"` and pin your version accordingly.

## In this section
**Language Model**
[Generate text, structured objects, and streaming responses](https://effect.plants.sh/ai/language-model/)
    against a provider-agnostic model, with usage and finish-reason metadata.

**Tools**
[Define tools and toolkits](https://effect.plants.sh/ai/tools/) the model can call. The framework
    resolves parameters, runs your handlers, and feeds results back to the model.

**Chat**
[Stateful chat sessions](https://effect.plants.sh/ai/chat/) that track conversation history
    automatically — the foundation for assistants and agentic loops.

**Agent Loops**
[Build a production agent](https://effect.plants.sh/ai/agent-loops/) — a bounded tool-calling loop
    with per-turn tracing, streaming, context compaction, steering, and interruption.

## How it fits together

There are three layers to an AI feature in Effect:

1. **The program** — your business logic, written against the abstract
   `LanguageModel`, `Tool`, `Toolkit`, and `Chat` modules. No provider details.
2. **The model** — a `Layer` from a provider package (e.g.
   `OpenAiLanguageModel.model("gpt-5.2")`) that provides a concrete
   `LanguageModel` plus `Model.ProviderName` / `Model.ModelName` metadata.
3. **The client** — a `Layer` holding credentials and an
   [`HttpClient`](https://effect.plants.sh/http-client/) (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](https://effect.plants.sh/testing/), or try several providers in sequence with an
`ExecutionPlan` — all without touching your business logic.