Migrating Langchain To Pydantic AI
PydanticOfficialPublished by Pydantic
- Skill
- Workflow
- Software development
- MIT
- No issues found
AutoGineer summary
Written by AutoGineer from the skill’s own files, not by the author
This skill provides a structured methodology for porting existing AI applications from the LangChain ecosystem to Pydantic AI. It emphasizes preserving application behavior over matching framework structures, advocating for a slice-based migration approach. The guide covers mapping core agent loops, handling complex state and persistence, and translating Deep Agents harness features into Pydantic AI primitives. It includes specific guidance on managing semantic gaps, verifying observability, and ensuring production readiness through characterization tests.
What it does
- Provides a step-by-step procedure for identifying and migrating functional slices of an application.
- Maps LangChain/LangGraph concepts to Pydantic AI primitives.
- Offers strategies for translating Deep Agents harness features like filesystem tools, subagents, and memory.
- Defines best practices for handling dependencies, typed invariants, and observability.
- Includes guidance on managing semantic differences and verifying parity through testing.
- Outlines the process for production cutover and verification.
When to use it
- When you need to migrate an existing LangChain or LangGraph application to Pydantic AI.
- When your application uses Deep Agents and requires a transition to Pydantic AI Harness.
- When you need to ensure behavioral parity during a framework migration.
- When you need to resolve semantic differences between LangChain and Pydantic AI implementations.
Advantages
- Focuses on behavioral preservation rather than superficial code matching.
- Provides a clear, risk-aware path for complex agentic systems.
- Includes specific mapping references for core loops and harness features.
- Encourages the use of typed dependencies for better reliability.
- Promotes a test-driven approach to ensure migration accuracy.
Usage examples
- “How do I migrate a simple LangChain agent to Pydantic AI?”
- The agent will guide you to identify the agent's tools and system prompt, then show you how to define a Pydantic AI Agent with typed dependencies and instructions, replacing the LangChain constructor.
- “How should I handle Deep Agents subagents in Pydantic AI?”
- The agent will explain how to map the subagent's filesystem, skills, and memory middleware to Pydantic AI Harness capabilities or custom application services.
Install
Download the skill as a ZIP:
https://autogineer.com/agent-skills/pydantic/migrating-langchain-to-pydantic-ai/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip migrating-langchain-to-pydantic-ai.zip -d .agents/skills
Documentation by Pydantic
Migrate LangChain, LangGraph, and Deep Agents to Pydantic AI
Preserve behavior, not framework shape. Migrate the smallest behaviorally complete slice and leave application infrastructure outside that slice unchanged. LangChain, LangGraph, and Deep Agents are one source ecosystem; Pydantic AI, pydantic_graph, and Pydantic AI Harness are the matching target ecosystem, and this skill maps across all of it.
Work from the running application
Read repository instructions, dependency files, tests, and the actual runtime entrypoints. Identify the installed LangChain, LangGraph, Deep Agents, Pydantic AI, and Harness versions.
Trace one representative request through prompts, retrieval, model and tool calls, state, persistence, interrupts, emitted events, tracing/metrics callbacks, and the public result. Inspect every caller and sibling endpoint that consumes the migrated component; a narrow implementation slice can still have several public contracts. Include keyword parameter names and the sync, async, callback, and streaming forms callers actually use. Record only contracts those paths actually use.
Run the cheapest useful baseline. When the migration surface is broad or unclear, search dependency files and source for
langchain,langgraph,langsmith, anddeepagents, then confirm findings against imports, factories, and call sites. Resolve wherecreate_deep_agentcomes from: the upstream package and a vendored copy that reproduces its contracts both count as Deep Agents.Classify the slice before choosing a target:
Chain or LCEL pipeline: keep deterministic retrieval and transformation in plain Python; use a Pydantic AI agent only where a model/tool loop adds value.
LangChain agent: normally use one reusable
pydantic_ai.Agentwith typed dependencies, tools, and outputs.Direct LangGraph workflow: use plain async Python for simple fixed control flow, or
pydantic_graphwhen explicit typed nodes and branching remain useful. Treat persistence as a separate design decision.Deep Agents harness:
create_deep_agentbundles file tools, shell execution, subagent delegation, summarization, skills, memory, permissions, prompt caching, and approval middleware on top of the LangChain agent loop, and a harness profile can add or hide more. Migrate the loop with the LangChain mappings, then map each bundled feature the slice actually uses to a Harness capability, a core primitive, or an application service with Deep Agents Mapping. Inventory implicit defaults the application code never mentions.Product runtime: retain queues, configured database backends, sandboxes, auth, schedulers, webhooks, tracing, and transport adapters unless the user placed them in scope. Extend an existing application seam before creating a parallel persistence or provider subsystem.
Add or preserve deterministic characterization tests, then migrate one vertical slice behind the existing public boundary.
Run the original tests and focused parity tests. Classify each observed contract by its evidence; never describe the migration as one-to-one merely because the happy path or trace shape looks similar.
Read Concept Mapping for the detected source features. Read Deep Agents Mapping whenever deepagents is in the slice. Read Semantic Gaps only for state, middleware, retries, approval, concurrency, streaming, or other behavior where similar-looking APIs may differ. Use Workaround Recipes after a concrete gap is identified, not as a mandatory checklist. Read Logfire Verification when adding observability, comparing source and target runs, or debugging a semantic difference. Read Verification and Cutover before a production cutover.
Explain semantic differences
When an observed source contract has no direct equivalent, explain it to the user before making a consequential design choice. State the source behavior, how the proposed Pydantic AI design differs, the user-visible or operational impact, and the available choices. Recommend one option and name its residual risk. Keep this proportional: do not turn ordinary import or naming changes into semantic warnings.
Do not stop at "unsupported." When nothing maps directly, recommend an existing core or Harness composition, a narrow adapter or application service, a new capability built from public primitives, or a core change, in that order of preference. Ask before choosing only when the options materially change behavior, architecture, public API, or scope.
Match rigor to risk
For a stateless chain or ordinary agent port, focused characterization tests and a short residual-risk note are enough. Do not require a semantic-gap register or durability exercise for behavior the source does not have.
For middleware, structured output transport, retrieval, tool retries, or streaming, probe the affected contract against the installed versions.
For checkpointed graphs, interrupts, approvals, durable execution, concurrent fan-out, or external side effects, create a migration ledger. Separate dependencies, messages, workflow state, checkpoint state, and long-term memory. Fit those owners into the repository's existing backend-selection and service interfaces where possible. Test restart, replay, correlation, authorization, and idempotency only to the extent the source promises them.
A
deepagentsdependency alone changes nothing. When the active slice callscreate_deep_agentor depends on its planning, filesystem, sandbox, skills, memory, subagent, permission, or deployment contracts, those are in-scope features with Harness or application owners, not a reason to stop. Files, sandboxes, permissions, subagents, and background work carry the same ledger and restart obligations as checkpointed graphs.
Pydantic AI defaults
Put authenticated identity, service clients, and configuration in typed dependencies, never model-chosen tool arguments.
Strengthen observed unstable seams, not the whole application: parameterize the agent's dependency and output types, and validate terminal choices, persisted workflow records, and framework adapters. Preserve stable public wire shapes and do not invent types for paths outside the migrated slice.
Preserve public request, response, error, and event shapes with a small adapter while callers migrate.
Keep retrieval, storage, provider, and transport integrations in place when they are outside the requested slice. Transitional LangChain integrations are acceptable when named and bounded.
Use Pydantic models for terminal structured output when that preserves the contract; retain an existing parser when changing the wire contract would expand the migration.
Do not force an
Agentonto deterministic LCEL orpydantic_graphonto everyStateGraph.Inspect the installed Pydantic AI API before choosing model classes, provider transports, hooks, streaming methods, or durable integrations.
Add
pydantic-ai-harnessonly for observed harness behavior: planning, workspace files, shell or sandboxed execution, Agent Skills, memory notebooks, repository context, model-directed subagents, model-agnostic compaction, tool-output limits, guardrails, spend limits, or step persistence. Add capabilities one at a time, import each from its owning public submodule, treatpydantic_ai_harness.experimental.*as version-sensitive, and run an import-and-construction smoke test in the target environment. Harness composes onto the core agent loop; it is not a second runtime and does not replace application infrastructure.When adding Pydantic AI, prefer a currently supported stable release. Use the newest compatible release unless that would expand the migration through an unrelated major/runtime upgrade; explain and pin any exception. Resolve the whole project from a clean environment and run an import probe because an existing environment can hide incompatible transitive versions. Prefer
pydantic-ai-slimwith only the required provider and integration extras when the dependency surface is bounded, and use the full distribution when its broader integrations are actually needed. Do not pin an older release merely to match a remembered example.If the source already uses LangSmith, Langfuse, or another observability system, do not replace it silently. Explain that Logfire is the first-party Pydantic AI integration and normally provides the most direct agent, model, tool, retry, error, usage, and timing experience. Contrast that with the continuity of retaining the current system, including its dashboards, alerts, evaluations, retention, and export pipeline; recommend a choice and obtain agreement before switching. Offer Logfire at application startup when no tracing system exists or the user chooses it, make content capture an explicit privacy decision, and keep executable contract tests as the authority for parity.
Completion
The slice is complete when every observed contract is either preserved by an executable check, intentionally changed by an accepted decision, or explicitly not applicable. An untested contract is unverified, not equivalent; an unresolved requested contract is unfinished work, not completion evidence. Constrain the slice or ask the user to accept the deferral. Remove LangChain, LangGraph, or Deep Agents dependencies only after no retained path needs them.
Files
- ATTRIBUTION.mdAdded by AutoGineer885 B
- LICENSELicence file added by AutoGineer1.1 KiB
- SKILL.md9.9 KiB
- agents/openai.yaml394 B
- references/CONCEPT-MAPPING.md16.2 KiB
- references/DEEP-AGENTS-MAPPING.md24.5 KiB
- references/LOGFIRE-VERIFICATION.md10.2 KiB
- references/SEMANTIC-GAPS.md21.6 KiB
- references/VERIFICATION-AND-CUTOVER.md12.3 KiB
- references/WORKAROUND-RECIPES.md18.0 KiB
references/WORKAROUND-RECIPES.md
Validated Workaround Recipes
Use this reference after finding a non-1:1 mapping. The job is not complete until the gap has a working Pydantic AI construction, a parity probe, and a named owner—or is an explicit blocker.
Contents
Required outcomes
Choose the replacement mechanism
Prompt replacement and history
Middleware and local tool retry
Structured output and return-direct tools
Conversational interrupts, approval, and durable resume
Workflow state, fan-out, and reducers
Streaming and event contracts
Limits and persisted budgets
Evidence rules
Required outcomes
Assign every semantic-gap row one outcome:
| Outcome | Meaning |
|---|---|
verified-equivalent | A Pydantic AI primitive preserves the required public behavior in executable source/target checks. |
verified-adapter | Small application or capability code closes the gap, and executable checks prove the public contract. |
intentional-change | The semantic difference and impact were explained and explicitly accepted. |
external-owner | A named application or infrastructure component preserves the contract, with evidence at that boundary. |
not-applicable | The observed source path does not provide or consume this behavior. |
unverified | A candidate construction exists, but the target project/version or operational boundary has not passed its own parity test. |
blocked | No acceptable construction has passed. Do not migrate that slice. |
Do not leave a row at "redesign" or "not 1:1." Select the most native mechanism that can preserve the behavior, write the smallest source/target reproduction, and measure both. Keep spike code outside the product and skill; promote only stable contract tests.
Choose the replacement mechanism
| Source behavior | First Pydantic AI construction to spike | Fallback owner |
|---|---|---|
| current developer policy | instructions or one dynamic @agent.instructions function | model-request hook |
| replace-not-compose prompt middleware | ordered Hooks.on.before_model_request replacements | request adapter |
| missing/untrusted historical system prompt | ReinjectSystemPrompt(replace_existing=True) | server history adapter |
| before/after/wrap middleware | Hooks; use on.model_request, on.tool_execute, or another wrapper hook for nesting | custom AbstractCapability |
| same-handler transient tool retry | Hooks.on.tool_execute or service-client retry | application service |
| model-correctable tool arguments | ModelRetry / tool retry budget | agent |
| provider-native structured response | NativeOutput | provider-specific adapter |
| tool-based structured response | ToolOutput | output adapter |
return_direct=True | named output function wrapped in ToolOutput | explicit application route |
| HITL tool approval | deferred tools plus authenticated pending-action store | durable workflow |
| checkpoint/replay | DBOSAgent, TemporalAgent, PrefectAgent, Restate, Kitaru, or another selected durable runtime | application workflow |
| graph state and reducers | typed application state or pydantic_graph; branch-local results plus explicit reducer | orchestration layer |
| complete execution with events | run(event_stream_handler=...), run_stream_events(), or iter() | event adapter |
| per-run request/tool limits | UsageLimits and shared RunUsage | application budget service |
| persisted thread/graph-step limits | per-thread serialization or transactional reservation plus settlement/reconciliation | workflow store |
Prompt replacement and history
If the desired policy is composition, put all policy fragments in instructions. If the source truly uses last-replacement-wins behavior, reproduce that rather than accidentally strengthening or weakening the prompt.
The simplest validated route is to collapse a last-replacement-wins source chain into one effective dynamic instruction function, provided overwritten prompt functions are pure and do not own required side effects. If evaluating every replacement is itself behavioral, ordered before_model_request hooks can replace the latest request instructions.
Do not rely on a success-only after_run hook to clean request instructions: failed or cancelled runs bypass it. If the source does not checkpoint request prompts, omit boundary-only instruction fields in the application message serializer, or use a reversible run wrapper whose finally path is proved under success, failure, and cancellation. Probe at least two dependency values plus a continued conversation and compare both actual model input and persisted application history.
For UI or database history that omits system prompts, use:
# ruff: noqa: F821
from pydantic_ai import Agent
from pydantic_ai.capabilities import ReinjectSystemPrompt
agent = Agent(
model,
system_prompt='Authoritative server policy',
capabilities=[ReinjectSystemPrompt(replace_existing=True)],
)replace_existing=True is important for untrusted history: it removes client-supplied system prompts before adding the server policy. This solves prompt authority, not general message conversion. Keep a fail-closed converter for the exact LangChain message subset the application retains; reject tool, reasoning, multimodal, or provider metadata until their round-trip is tested.
Middleware and local tool retry
Pydantic AI Hooks wrapper hooks preserve nested control flow and can short-circuit by returning a response without calling the handler. Register separate capabilities in source order and trace their exact before/after sequence. Current decorator names omit wrap_: use @hooks.on.model_request and @hooks.on.tool_execute.
Use a tool-execution wrapper when LangChain retries the same handler locally. A validated shape is:
# ruff: noqa: F821
from typing import Any
from pydantic_ai import RunContext
from pydantic_ai.capabilities import Hooks
retry_hooks = Hooks()
@retry_hooks.on.tool_execute(tools=['lookup'])
async def retry_lookup(
ctx: RunContext,
*,
call,
tool_def,
args: dict[str, Any],
handler,
) -> Any:
for attempt in range(2):
try:
return await handler(args)
except TransientServiceError:
if attempt == 1:
raise
raise AssertionError('unreachable')This can match LangChain at two handler executions but only the original tool-request model round plus finalization. ModelRetry is deliberately different: it asks the model to issue a corrected call and therefore adds a model request. Add exception filtering, backoff, timeout, observability, exhaustion behavior, and idempotency appropriate to the service; never blindly retry side effects.
Use a custom capability rather than a pile of hooks when a source middleware unit owns tools, instructions, settings, and lifecycle behavior together. Use a model wrapper for provider failover/transport policy, and application code for routing or persisted workflow-state jumps.
Structured output and return-direct tools
Match the source transport explicitly:
# ruff: noqa: F821
from pydantic_ai import Agent, NativeOutput, ToolOutput
native_agent = Agent(model, output_type=NativeOutput(Answer))
tool_agent = Agent(model, output_type=ToolOutput(Answer, name='Answer'))A parity probe must inspect the model request: native mode has an output object and no output tool; tool mode exposes the named output tool. Also compare invalid-output retries, co-emitted function tools, final DTO, and provider fallback.
When a LangChain tool uses return_direct=True, and the model must choose it as a terminal action, migrate it as an output function rather than a normal function tool:
# ruff: noqa: F821, I001
from pydantic_ai import Agent, RunContext, ToolOutput
def export_report(ctx: RunContext[Deps], report_id: str) -> str:
return ctx.deps.reports.export(ctx.deps.customer_id, report_id)
agent = Agent(
model,
deps_type=Deps,
output_type=ToolOutput(export_report, name='export_report'),
)A disposable skill-development spike on Pydantic AI 2.10.1.dev24 observed one output-function execution and one model call. Treat that as a candidate construction, not validation for the target project: rerun the source/target probe before assigning verified-equivalent. It changes the model contract from "optional ordinary tool" to "terminal output choice," so use a union/list of output choices when other terminal outcomes exist. Output functions can run on partial values under run_stream(); guard side effects with ctx.partial_output or use a complete-execution API.
Conversational interrupts, approval, and durable resume
First distinguish two different source contracts:
A conversational interrupt pauses a workflow to ask the user for missing information, then resumes from that answer. It is not authorization for a protected effect.
A tool approval binds an authenticated decision to a particular tool call and arguments before a protected effect runs.
For a conversational interrupt, keep the pending question, workflow phase, authenticated owner, thread ID, and any completed pre-interrupt work in application state. Resume by loading that state and adding the answer as user protocol content, unless the source deliberately treats it as a control signal; putting the answer only in transient instructions can make it disappear from later conversation history. Do not re-run pre-interrupt model calls merely to reconstruct context. Reuse or extend the repository's configured persistence interface instead of silently introducing a local-only store. Preserve existing anonymous/optional identity behavior unless the application owner accepts a stronger identity contract. Test a fresh process/agent instance against the same store, same-thread correlation, cross-user rejection when identity exists, and whether the source repeats the interrupted node. If the source promises checkpoint forks, pending writes, or replay, a linear application record is only a bounded adapter and must say so.
For protected-tool approval, use requires_approval=True or raise ApprovalRequired, then persist the returned DeferredToolRequests. The application record should include:
application approval ID and Pydantic tool-call ID;
authenticated tenant, initiator, and permitted approver;
tool name and original validated arguments;
serializable dependencies or stable references to reconstruct them;
complete server-owned message history;
pending/consuming/completed/manual-reconciliation status, result, claim owner, lease expiry, attempt count, and fencing/consumption version;
business idempotency key plus an authoritative effect receipt or reconciliation reference when the external system provides one.
On resume, authenticate first and atomically claim a pending or safely expired consuming row with a bounded lease and new fencing version. Return the cached result for completed; report an unexpired claim as in progress. Before reclaiming an expired lease, reconcile the protected effect by idempotency key or authoritative receipt: finalize a known result, retry only when the effect is known not to have happened or the external API guarantees safe replay, and move an unknowable outcome to manual reconciliation instead of blindly rerunning it. Reconstruct the original history/dependencies and pass server-created DeferredToolResults; only the current fenced claimant may persist completion. Unknown, foreign, modified, or stale claims must fail before the agent or tool executes.
A disposable SQLite development spike exercised this adapter across a fresh service instance, including foreign-principal rejection and a simulated crash after the tool. The tool was attempted twice after recovery but its unique business idempotency key produced one durable effect. This is design evidence, not target-project validation or a claim that arbitrary external APIs are exactly once; keep the outcome unverified until the selected store passes the same probe.
For long waits and process recovery, put the loop in a durable runtime. Pydantic AI supplies wrappers such as DBOSAgent, TemporalAgent, and PrefectAgent; Restate and Kitaru also provide integrations. A disposable two-process DBOS development spike with a stable agent name and workflow ID returned the persisted first result without repeating the model call. This narrows the candidate design but does not change the target outcome from unverified. For DBOS, decorate non-deterministic or I/O tool functions with @DBOS.step; they are not automatically durable merely because the agent is wrapped.
Run real process-kill/restart tests against the selected production backend after claim, before the effect, after an unknown effect outcome, and before completion persistence. Prove expired-lease recovery, stale-worker fencing, cached-result replay, and the manual-reconciliation path. Keep stable agent/toolset IDs, serializable dependencies, and explicit workflow signals/events for approval. Do not generalize DBOS evidence to Temporal, Prefect, Restate, Kitaru, or a different database.
Workflow state, fan-out, and reducers
Keep model messages out of workflow state. Persist plans, next step, joins, pending actions, counters, and domain progress in a typed workflow record or durable runtime. Pass only model protocol history through message_history.
For a fixed fan-out, create branch-local tasks and reduce after they finish. Preserve source ordering deliberately, for example by keeping the input index and sorting before the reducer. Use asyncio.TaskGroup when sibling cancellation on failure is required; use gather(..., return_exceptions=True) only when partial results are part of the contract. Put concurrency limits in a semaphore.
Use pydantic_graph when the state machine itself needs typed, inspectable nodes and joins. It is not a checkpoint replacement: current graph APIs do not supply LangGraph-style built-in persistence. Wrap the workflow in a durable runtime or persist transitions in application code.
For model-emitted function tools, Pydantic AI runs tools concurrently by default. Set sequential=True on a barrier tool, or use with agent.parallel_tool_call_execution_mode('sequential') for a whole run. These settings control tool execution; they do not reproduce LangGraph reducers or Send branch state.
Streaming and event contracts
Do not expose framework events as the public API. Normalize source and target into an application envelope with version, run ID, sequence, correlation/tool-call ID, event kind, payload, and terminal/error semantics.
Use run_stream() only when committing the first matching output is the intended contract. When all function tools, retries, and side effects must complete, use run(event_stream_handler=...), run_stream_events(), or iter(), then emit the application terminal event from the completed AgentRunResult.
When adapting run_stream_events() or iter() to an existing token stream, handle both the initial text carried by PartStartEvent and later text in PartDeltaEvent. A consumer that forwards only deltas silently drops the first chunk. Forward events as they arrive rather than collecting them until the run finishes when the source promises live streaming; event order with buffered delivery does not preserve time to first event, backpressure, or cancellation. Keep live event forwarding separate from final-result collection so the application can emit its terminal message from the completed run.
Probe token/tool/final ordering, co-emitted output and tools, consumer cancellation, cleanup, backpressure, reconnect cursor, and duplicate delivery. Durable runtimes have different streaming constraints: validate the selected wrapper rather than assuming core-agent streaming behavior survives unchanged.
Limits and persisted budgets
Use UsageLimits for Pydantic AI units and reuse one RunUsage object when several runs or child agents share a budget:
# ruff: noqa: F704, F821, PLE1142
from pydantic_ai import RunUsage, UsageLimits
usage = RunUsage()
limits = UsageLimits(request_limit=12, tool_calls_limit=20)
result = await agent.run(prompt, usage=usage, usage_limits=limits)This does not implement LangGraph recursion_limit or LangChain's persisted per-thread model-call counter. Keep a workflow-step counter and thread budget in the application store. For a strict shared budget, either serialize all work for one thread or reserve capacity transactionally before dispatch with compare-and-swap/row locking, then settle measured usage and reconcile abandoned reservations after crashes. A check-before-call followed by an update-after-call is not safe under concurrency or process failure. Preserve the source failure shape if callers depend on a synthetic terminal message rather than an exception.
Test boundary minus one, boundary, and boundary plus one. Pydantic AI checks a parallel tool-call batch atomically against tool_calls_limit; prove whether the source instead allows a prefix. Include child-agent usage, replayed steps, and resumed runs.
Evidence rules
Keep workaround spikes disposable and deterministic:
Print versions, module origins, and the Pydantic AI checkout SHA.
Use real LangChain/LangGraph and Pydantic AI APIs with fake/function models; do not mock the behavior under comparison.
Count model calls, tool calls, side effects, persisted records, and events.
Add failure and restart injection where the workaround owns retries, durability, or approval.
State the narrow guarantee proved and what remains unproved.
Delete the spike after extracting the recipe; add a stable product test for the public contract.
Treat each construction as a candidate pattern, not proof for the target project. Re-run the relevant behavioral check against its installed versions.
Requirements and compatibility
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta
“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.
Security
No issues found by our static scan· No issues found
A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.
Attribution and licence
- Published by
- Pydantic
- Publisher
- Pydantic (Official)
- Source
- pydantic/skills · skills/migrating-langchain-to-pydantic-ai · commit 98f591c
- Licence
- MIT License (redistribution allowed)
- LICENSE (added by AutoGineer from LICENSE)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
- Also distributed in
- pydantic/skills
AutoGineer is not affiliated with or endorsed by Pydantic or Pydantic.
Download ZIP
The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download migrating-langchain-to-pydantic-ai.zip