Artificial Intelligence

How to choose an AI SDK: why the fear of lock-in is a mistake and how to decide based on your app's format

The fear of being locked into an AI provider is a common mistake. Learn how to choose the best SDK based on your project's format and productivity.

How to choose an AI SDK: why the fear of lock-in is a mistake and how to decide based on your app's format

For a long time, I did the math wrong in my head. When I was about to start an app with AI, I would discard the Claude Agent SDK and the Vercel AI SDK almost out of reflex — “those must be tied to their provider,” I thought. Then I would go with Genkit, thinking it was the only “free” option. Until the day the Ollama launcher showed me, right to my face, that I was wrong the whole time.

The premise that cost me dearly

The question that stalled everything was: “what if one day I want to switch models? Will I be held hostage by Anthropic / Vercel?”. With that fear, the selection criteria became the vendor — and not the problem I was solving. It is a silent error, because it looks like prudence.

Ollama toppled the premise

I ran the ollama launch and the menu offered me, among other things, “Launch Claude Code (minimax-m3:cloud)” and “Launch OpenCode”. Notice the detail: it was about to run Claude Code — which uses the Claude Agent SDK under the hood — with a minimax-m3 model, which is not from Anthropic. How? It just swaps the base URL pointer.

BASH
# É só isto que o launcher do Ollama faz por baixo dos panos:export ANTHROPIC_BASE_URL=http://localhost:11434   # endpoint Anthropic-compat do Ollamaexport ANTHROPIC_MODEL=minimax-m3:cloudclaude            # Claude Code rodando um modelo NÃO-Claude, com subagentes e tudo

Zero code. A third-party model running under the Claude Code harness, just because Ollama exposes an endpoint compatible with the Anthropic protocol. If this applies to Claude Code, it applies to any app built on the same SDK.

The agnostic layer exists in all of them

After that realization, I went to look at the others. They all have the same fundamental mechanism: pointing to an endpoint + a normalization layer. Only the name changes:

SDK

How it points to another provider

Normalizes to

claude-agent-sdk

ANTHROPIC_BASE_URL (endpoint that speaks the Anthropic protocol); Bedrock/Vertex backends

shape Anthropic Messages

Vercel AI SDK

gateway() / createGateway({baseURL}) / createOpenAICompatible({baseURL})

neutral contract (text/tool-call/reasoning)

Genkit

provider plugins (googleAI, openai-compat…)

Genkit model abstraction

O vendor não é critério. A escolha real é qual batteries-included bate com o formato do app.

— a régua que eu deveria ter usado desde o começo

The four SDKs and what each one already brings ready-made

They are not at the same level of abstraction — and that is exactly what decides the choice. It is not “which one is freer” (all are), but rather “which one already solves the type of app I am building”.

claude-agent-sdk — “Claude Code as a library”

It is a complete agent harness. It gives you the five most annoying primitives to build for free: tool hooks (deterministic guard), human-in-the-loop approval, AskUserQuestion as a protocol, subagents via native tool, and in-process MCP. Fits: autonomous code agent with security and approval.

Genkit — GenAI app framework

Strong in first-class RAG (retriever/indexer/embedder), orchestration flows, and OpenTelemetry observability with dev UI. Fits: content generation, RAG, pipelines, tracing. It was the right choice for my editorial — just for the wrong reason at the time.

pydantic-ai — typed agents in Python

Typed agents and tools, structured output validated by Pydantic, multi-agent. Lightweight, no ready-made RAG/flows/observability. Fits: typed agent logic. I tested it for the editorial and it didn't fit — it is a battery for another format.

Vercel AI SDK — model + tools + provider (+ UI)

streamTextAI SDK CoregenerateText with neutral parts, ToolLoopAgentthe best agnostic provider story, and UI hooks (useChat). Fits: truly provider-neutral (first-class OpenAI-native) + React UI integration.

Capability (comes ready?)

claude-agent-sdk

Vercel AI SDK

Genkit

pydantic-ai

Agent loop

Guard / tool hooks

✓ native

Human approval

Native subagents

~

First-class RAG

✓✓

Observability / tracing

basic

basic

✓ OTel

basic

UI hooks (useChat)

Provider agnostic

via base-URL

✓ neutral

✓ plugins

The decision ruler

After all this, the question I ask today, before any line of code, is just one: what is the app format?

❌ How I used to decide

“Which SDK locks me in the least to the vendor?”

Result: I chose out of fear, not because of the problem.

✅ How I decide now

“Which batteries-included matches the app format?”

Result: the tool that already solves the right type of problem.

  • Autonomous code agent (security, approval, subagents) → claude-agent-sdk

  • Content + RAG + flows + observability → Genkit

  • Typed agent logic (Python) → pydantic-ai

  • Truly provider-neutral + UI → Vercel AI SDK

Bonus: the settingSources trap

A technical surprise worth keeping in mind, if you use claude-agent-sdk: your agent inherits the Claude Code environment (hooks, plugins, CLAUDE.md, permission rules) even if it is not Claude Code. And it is not because of the API key — it is the default of settingSourcessettingSources

TYPESCRIPT
// sdk.d.ts: "When omitted, all sources are loaded (matches CLI defaults).//           Pass [] to disable filesystem settings (SDK isolation mode)."buildAgentOptions({  // settingSources OMITIDO  -> carrega ~/.claude inteiro (hooks/CLAUDE.md/perms)  settingSources: [],        // <- modo ISOLAMENTO: só as regras do teu app})

, not the key. Make it explicit — accidental inheritance is debt.

  • What I take to every new projectVendor is not a criterion. Every agent SDK is agnostic via base-URL / gateway / plugins.

  • Decide by the app format, not by the brand or fear of lock-in.

  • Batteries-included > theoretical agnosticism. What comes ready-made saves weeks.Testing and migrating without guilt is correct selection, not an error (that's how I went from pydantic-ai to Genkit in a content app).

  • What is reusable is UI/infra, not the engine: extract chat, streaming, and retriever into a common package.

  • The good part about discovering you were wrong is that the remaining ruler is simple and reusable.Not “which SDK is the best” — but rather

which SDK is the best for this app. app.