DEV Community

Cover image for PydanticAI คืออะไร: คู่มือเฟรมเวิร์กเอเจนต์ Python แบบ Type-Safe
Thanawat Wongchai
Thanawat Wongchai

Posted on • Originally published at apidog.com

PydanticAI คืออะไร: คู่มือเฟรมเวิร์กเอเจนต์ Python แบบ Type-Safe

หากคุณเคยส่งมอบฟีเจอร์ LLM แล้วเจอ JSON รูปแบบผิดใน production, PydanticAI ถูกออกแบบมาเพื่อแก้ปัญหานี้โดยตรง มันคือเฟรมเวิร์กเอเจนต์ Python จากทีมเดียวกับ Pydantic ที่โฟกัสเอาต์พุตแบบ type-safe และผ่าน validation เหมาะกับงานที่ผลลัพธ์จากโมเดลต้องถูกส่งต่อเข้าโค้ดจริง เช่น API, database, billing flow หรือ workflow อัตโนมัติ บทความนี้สรุปวิธีใช้ PydanticAI แบบลงมือทำ และเปรียบเทียบกับเฟรมเวิร์ก Python อื่น เช่น LangGraph

ลองใช้ Apidog วันนี้

PydanticAI คืออะไร

PydanticAI เป็นเฟรมเวิร์กเอเจนต์แบบโอเพนซอร์สสำหรับ Python ที่ไม่ผูกกับผู้ให้บริการโมเดลใดโมเดลหนึ่ง ทีมผู้ดูแลคือทีมเดียวกับ Pydantic Validation และ Pydantic Logfire เป้าหมายหลักคือทำให้การสร้างเอเจนต์มีประสบการณ์ใกล้เคียง FastAPI: ประกาศ schema ชัดเจน, validate อัตโนมัติ, และทำงานร่วมกับ type checker ได้ดี

Pydantic AI

แนวคิดหลักคือคุณกำหนดว่าเอเจนต์ต้องทำอะไร ใช้เครื่องมืออะไรได้บ้าง และเอาต์พุตต้องมีรูปแบบแบบใด จากนั้น PydanticAI จะจัดการการเรียกโมเดล ตรวจสอบผลลัพธ์กับโมเดล Pydantic และ retry เมื่อโมเดลตอบกลับมาไม่ตรง schema

โปรเจกต์นี้ออกเวอร์ชัน v2.0.0 ที่เสถียรเมื่อวันที่ 23 มิถุนายน 2026 หลังผ่านช่วงเบต้าหลายรอบ เวอร์ชัน 2 เน้นการออกแบบแบบ harness-first โดยให้เครื่องมือ, hooks, คำสั่ง และการตั้งค่าโมเดลประกอบกันเป็นหน่วยที่นำกลับมาใช้ซ้ำได้

ติดตั้งได้ด้วย:

pip install pydantic-ai
Enter fullscreen mode Exit fullscreen mode

หรือถ้าใช้ uv:

uv add pydantic-ai
Enter fullscreen mode Exit fullscreen mode

ทำไม type safety จึงสำคัญกับเอเจนต์

LLM ไม่ได้ให้ผลลัพธ์ที่แน่นอนเสมอไป คำถามเดียวกันอาจได้คำตอบคนละรูปแบบ ซึ่งพอรับได้ใน chatbot แต่จะกลายเป็นปัญหาทันทีเมื่อเอาต์พุตถูกส่งเข้าโค้ดจริง เช่น:

  • เขียนข้อมูลลงฐานข้อมูล
  • เรียก REST API ถัดไป
  • คำนวณราคา
  • เปิด ticket
  • trigger workflow อัตโนมัติ

ปัญหาที่พบบ่อยคือโมเดล “ส่วนใหญ่” ส่ง JSON ถูกต้อง แต่บางครั้งขาด field, ใช้ type ผิด, หรือห่อ JSON ด้วยข้อความอธิบาย ทำให้ parser หรือ pipeline พังใน production สุดท้ายทีมต้องเขียน regex cleanup, defensive parsing และ retry loop เอง

PydanticAI แก้จุดนี้โดยให้คุณประกาศสัญญาของเอาต์พุตผ่าน output_type:

from pydantic import BaseModel
from pydantic_ai import Agent

class SupportTicket(BaseModel):
    category: str
    priority: int
    summary: str

agent = Agent(
    'openai:gpt-4o',
    output_type=SupportTicket,
)

result = agent.run_sync('My payment failed three times today.')

ticket = result.output
print(ticket.category)
print(ticket.priority)
print(ticket.summary)
Enter fullscreen mode Exit fullscreen mode

ผลลัพธ์ที่คุณได้คือ object ที่ผ่าน validation แล้ว ไม่ใช่ string ที่ต้องเดาเอง ถ้าโมเดลส่ง priority เป็นข้อความ หรือไม่ส่ง summary กลับมา PydanticAI จะส่ง validation error กลับไปให้ LLM และขอให้ลองตอบใหม่

หลักการเดียวกันใช้กับ tool arguments ด้วย เมื่อโมเดลเรียกใช้เครื่องมือ PydanticAI จะตรวจสอบ argument จาก type hints ก่อนเรียกฟังก์ชันจริง ทำให้ input ที่ผิดไม่ไหลเข้า business logic ของคุณ

แนวคิดหลักของ PydanticAI

1. Agent

Agent คือจุดเริ่มต้นหลัก คุณสร้างเอเจนต์ด้วย model identifier และคำสั่งเสริม:

from pydantic_ai import Agent

agent = Agent(
    'anthropic:claude-sonnet-4-6',
    instructions='Be concise, reply with one sentence.',
)

result = agent.run_sync('Where does "hello world" come from?')
print(result.output)
Enter fullscreen mode Exit fullscreen mode

การสลับผู้ให้บริการมักทำได้โดยเปลี่ยน model string เพียงบรรทัดเดียว เช่นจาก Anthropic เป็น OpenAI:

agent = Agent(
    'openai:gpt-4o',
    instructions='Be concise, reply with one sentence.',
)
Enter fullscreen mode Exit fullscreen mode

2. Typed output

ใช้ output_type เมื่อต้องการเอาต์พุตแบบมี schema:

from pydantic import BaseModel, Field
from pydantic_ai import Agent

class ProductSummary(BaseModel):
    name: str
    price: float
    tags: list[str] = Field(default_factory=list)

agent = Agent(
    'openai:gpt-4o',
    output_type=ProductSummary,
)

result = agent.run_sync(
    'Extract product info: Wireless mouse, 29.99 USD, gaming, bluetooth'
)

product = result.output

print(product.name)   # str
print(product.price)  # float
print(product.tags)   # list[str]
Enter fullscreen mode Exit fullscreen mode

ข้อดีคือ IDE และ type checker เห็น field ทั้งหมด:

def save_product(product: ProductSummary) -> None:
    # product.price เป็น float ที่ validate แล้ว
    ...
Enter fullscreen mode Exit fullscreen mode

คุณไม่ต้องเขียน logic แบบนี้เอง:

import json

raw = call_llm(...)
data = json.loads(raw)

if 'price' not in data:
    ...
Enter fullscreen mode Exit fullscreen mode

3. Tools

Tools คือฟังก์ชันที่โมเดลสามารถเรียกใช้เพื่อเข้าถึงระบบภายนอก เช่น database, REST API หรือ calculation logic

ลงทะเบียน tool ด้วย @agent.tool:

from pydantic_ai import Agent, RunContext

agent = Agent(
    'openai:gpt-4o',
    deps_type=str,
)

@agent.tool
async def get_user_balance(
    ctx: RunContext[str],
    account_id: str,
) -> float:
    """Return the current balance for an account."""
    return await lookup_balance(ctx.deps, account_id)
Enter fullscreen mode Exit fullscreen mode

PydanticAI จะอ่าน type hints และ docstring เพื่อสร้าง schema ที่โมเดลเห็น จากนั้น validate ทุก tool call ก่อนเรียกฟังก์ชันจริง

ตัวอย่าง flow:

  1. ผู้ใช้ถามว่า “บัญชี A123 เหลือเงินเท่าไร”
  2. โมเดลตัดสินใจเรียก get_user_balance
  3. PydanticAI ตรวจว่า account_id เป็น str
  4. ฟังก์ชัน tool ทำงาน
  5. ผลลัพธ์ถูกส่งกลับให้โมเดลใช้ตอบผู้ใช้

4. Dependencies

เอเจนต์ production มักต้องใช้ dependency เช่น:

  • database connection
  • HTTP client
  • current user
  • API key
  • feature flag
  • service object

PydanticAI ใช้ dependency injection ผ่าน deps_type และ RunContext:

from dataclasses import dataclass
from pydantic_ai import Agent, RunContext

@dataclass
class Deps:
    api_base_url: str
    auth_token: str

agent = Agent(
    'openai:gpt-4o',
    deps_type=Deps,
)

@agent.tool
async def get_order_status(
    ctx: RunContext[Deps],
    order_id: str,
) -> str:
    """Get the status of an order."""
    return await fetch_order_status(
        base_url=ctx.deps.api_base_url,
        token=ctx.deps.auth_token,
        order_id=order_id,
    )

deps = Deps(
    api_base_url='https://api.example.com',
    auth_token='secret',
)

result = agent.run_sync(
    'Check order ORD-123',
    deps=deps,
)
Enter fullscreen mode Exit fullscreen mode

ข้อดีคือทดสอบง่ายขึ้น เพราะคุณสามารถ inject fake dependency ใน test ได้โดยไม่ต้องแก้ logic ของ agent

5. Provider flexibility และ streaming

PydanticAI รองรับผู้ให้บริการหลายราย เช่น OpenAI, Anthropic, Gemini, DeepSeek, Grok, Cohere, Mistral, Perplexity รวมถึงตัวเลือกคลาวด์อย่าง Azure AI Foundry และ Amazon Bedrock และโมเดลที่โฮสต์เอง

การสลับ provider มักทำได้ด้วยการเปลี่ยน model string:

Agent('openai:gpt-4o')
Agent('anthropic:claude-sonnet-4-6')
Enter fullscreen mode Exit fullscreen mode

นอกจากนี้ยังรองรับการ stream เอาต์พุตแบบ structured พร้อม validation ระหว่างข้อมูลทยอยเข้ามา ทำให้แสดงผลลัพธ์บางส่วนได้โดยยังรักษา type guarantees และสามารถเชื่อมกับ Pydantic Logfire สำหรับ tracing, debugging และ cost tracking ได้

PydanticAI เทียบกับเฟรมเวิร์กเอเจนต์ Python อื่นอย่างไร

ไม่มีเฟรมเวิร์กเดียวที่ดีที่สุดสำหรับทุกงาน ให้เลือกตามลักษณะระบบที่ต้องสร้าง:

เฟรมเวิร์ก จุดแข็งหลัก เหมาะเมื่อคุณต้องการ
PydanticAI เอาต์พุตและ tool arguments แบบ type-safe พร้อม validation ความน่าเชื่อถือใน production และ data flow ที่มี schema ชัดเจน
LangGraph กราฟที่มี state และ control flow ชัดเจน workflow หลายขั้นตอน, แตกแขนง, ทำงานนาน
Google ADK การจัดระบบ multi-agent ใน ecosystem ของ Google integration กับ Gemini และ Vertex AI
OpenAI Agents SDK integration กับ OpenAI แน่น และรองรับ handoff stack ที่เน้น OpenAI และต้องการเริ่มเร็ว

จุดเด่นของ PydanticAI คือ validation layer ถ้าเอเจนต์ของคุณส่งข้อมูลเข้า service อื่น การรับประกันว่า output ตรงกับ Pydantic model จะช่วยลด runtime error ได้มาก

ในทางกลับกัน LangGraph เหมาะกว่าเมื่อคุณต้องการ state machine หรือ workflow ที่มีหลาย branch ส่วน OpenAI Agents SDK เหมาะเมื่อระบบของคุณผูกกับ OpenAI เป็นหลัก และต้องการฟีเจอร์เช่น agent handoff หรือ MCP server support

คุณยังสามารถใช้ร่วมกันได้ เช่น ใช้ LangGraph จัด orchestration ระดับ workflow และใช้ PydanticAI เป็นเลเยอร์ที่รับผิดชอบ typed output ภายในบาง node

ควรใช้ PydanticAI เมื่อใด

เลือก PydanticAI เมื่อ:

  • เอาต์พุตของเอเจนต์ต้องเข้าโค้ดจริง ไม่ใช่แค่แสดงใน chat UI
  • รูปแบบข้อมูลต้องถูกต้อง เช่นต้องมี field ครบและ type ถูก
  • คุณใช้ Pydantic หรือ FastAPI อยู่แล้ว
  • คุณต้องการให้ IDE และ type checker เข้าใจ flow ของเอเจนต์
  • คุณต้องการสลับ provider ได้โดยไม่ rewrite agent ใหม่
  • คุณต้องการ observability เช่น tracing และ debugging ผ่าน Logfire

พิจารณาเฟรมเวิร์กอื่นเมื่อ:

  • workflow มี branch ซับซ้อนมาก
  • ต้องเก็บ state ระยะยาวหลายขั้นตอน
  • ต้องการ explicit graph orchestration
  • ระบบผูกกับ provider เฉพาะและต้องใช้ feature เฉพาะของ provider นั้น

ตัวอย่าง implementation: สร้างเอเจนต์จัดหมวดหมู่ ticket

ตัวอย่างนี้เหมาะกับ use case ที่พบบ่อย: รับข้อความจากลูกค้า แล้วแปลงเป็น structured ticket

from typing import Literal
from pydantic import BaseModel, Field
from pydantic_ai import Agent

class TicketClassification(BaseModel):
    category: Literal['billing', 'technical', 'account', 'other']
    priority: Literal['low', 'medium', 'high']
    summary: str = Field(max_length=200)

agent = Agent(
    'openai:gpt-4o',
    output_type=TicketClassification,
    instructions=(
        'Classify customer support messages. '
        'Return a concise summary and choose the best category and priority.'
    ),
)

result = agent.run_sync(
    'I was charged twice this month and need a refund immediately.'
)

ticket = result.output

print(ticket.category)  # billing
print(ticket.priority)  # high
print(ticket.summary)
Enter fullscreen mode Exit fullscreen mode

จากนั้นคุณสามารถส่ง object นี้เข้า service ภายในได้โดยตรง:

def create_ticket(ticket: TicketClassification) -> None:
    # ticket ผ่าน validation แล้ว
    ...
Enter fullscreen mode Exit fullscreen mode

ตัวอย่าง implementation: Agent ที่เรียก REST API ผ่าน tool

สมมติคุณมี order API และต้องการให้เอเจนต์ตอบสถานะคำสั่งซื้อ:

from dataclasses import dataclass
import httpx
from pydantic_ai import Agent, RunContext

@dataclass
class Deps:
    client: httpx.AsyncClient
    api_base_url: str
    token: str

agent = Agent(
    'openai:gpt-4o',
    deps_type=Deps,
    instructions='Help users check order status.',
)

@agent.tool
async def get_order_status(
    ctx: RunContext[Deps],
    order_id: str,
) -> str:
    """Return order status by order ID."""
    response = await ctx.deps.client.get(
        f'{ctx.deps.api_base_url}/orders/{order_id}',
        headers={'Authorization': f'Bearer {ctx.deps.token}'},
    )
    response.raise_for_status()

    data = response.json()
    return data['status']
Enter fullscreen mode Exit fullscreen mode

รันเอเจนต์:

import asyncio
import httpx

async def main():
    async with httpx.AsyncClient() as client:
        deps = Deps(
            client=client,
            api_base_url='https://api.example.com',
            token='secret',
        )

        result = await agent.run(
            'What is the status of order ORD-123?',
            deps=deps,
        )

        print(result.output)

asyncio.run(main())
Enter fullscreen mode Exit fullscreen mode

จุดสำคัญคือ order_id ถูก validate ก่อน tool ทำงาน และ dependency ถูกส่งเข้า tool อย่างชัดเจนผ่าน RunContext

การทดสอบและ mock API ที่อยู่เบื้องหลังเอเจนต์

เอเจนต์ PydanticAI จะน่าเชื่อถือได้ก็ต่อเมื่อ API ที่มันเรียกใช้มีความน่าเชื่อถือด้วย การเรียกหนึ่งครั้งอาจแตะทั้ง LLM provider และ REST endpoint ภายในหรือ third-party API หลายตัว จุดเหล่านี้คือแหล่งของ flaky behavior, cost ที่คาดไม่ถึง และ response schema ที่ไม่ตรงกัน

PydanticAI ตรวจสอบ output จากโมเดลได้ แต่ไม่ได้ตรวจสอบแทนคุณว่า upstream API ที่ tool เรียกใช้นั้นส่ง response ตรงตามที่โค้ดคาดหวังหรือไม่

Apidog API testing

นี่คือจุดที่ Apidog ช่วยได้ Apidog ไม่ได้สร้างหรือ orchestrate เอเจนต์ แต่เป็นแพลตฟอร์ม API สำหรับทดสอบและ mock endpoint ที่เอเจนต์ของคุณพึ่งพา

แนวทางใช้งานจริง:

  • Mock LLM หรือ tool endpoint ระหว่างพัฒนา

    ชี้ tool ไปยัง mock API ที่คืน response คงที่ เพื่อลดการใช้ token และหลีกเลี่ยง rate limit ระหว่างปรับ logic

  • ตรวจ response schema ก่อนผูกกับ @agent.tool

    ใช้ API assertions ตรวจว่า endpoint จริงส่ง field และ type ตรงกับที่ tool คาดไว้

  • แยก environment สำหรับ local, staging และ CI

    เก็บ base URL, token และ provider key ใน environment แยกกัน เพื่อลด hard-coded config ในโค้ด

  • ทดสอบ LLM endpoint โดยตรง

    ถ้าคุณเรียก provider ผ่าน HTTP สามารถ ทดสอบ ChatGPT API ด้วย Apidog เพื่อตรวจ authentication, streaming และรูปแบบ tool call ก่อนนำไปใช้ใน agent

ตัวอย่าง workflow ที่แนะนำ:

  1. สร้าง API spec หรือ endpoint ใน Apidog
  2. สร้าง mock response สำหรับ tool endpoint
  3. ชี้ PydanticAI tool ไปยัง mock base URL ระหว่างพัฒนา
  4. เขียน assertion ตรวจ response schema
  5. เปลี่ยนเป็น staging หรือ production URL เมื่อพร้อม

หากต้องการลองใช้งาน ให้ ดาวน์โหลด Apidog แล้วเริ่มจาก mock endpoint หนึ่งตัวที่ agent ของคุณต้องเรียกใช้

คำถามที่พบบ่อย

PydanticAI ฟรีและเป็นโอเพนซอร์สหรือไม่?

ใช่ PydanticAI เป็นโอเพนซอร์สและติดตั้งจาก PyPI ได้ด้วย:

pip install pydantic-ai
Enter fullscreen mode Exit fullscreen mode

หรือ:

uv add pydantic-ai
Enter fullscreen mode Exit fullscreen mode

อย่างไรก็ตาม คุณยังต้องจ่ายค่าบริการ LLM provider ที่คุณใช้ เพราะเฟรมเวิร์กจะเรียก API เหล่านั้นแทนคุณ ระหว่างพัฒนา คุณสามารถลดค่าใช้จ่ายด้วยการ mock API response แทนการเรียกโมเดลจริงทุกครั้ง

PydanticAI ทำงานร่วมกับโมเดลใดได้บ้าง?

PydanticAI ไม่ผูกกับผู้ให้บริการรายเดียว เอกสารระบุการรองรับ OpenAI, Anthropic, Gemini, DeepSeek, Grok, Cohere, Mistral และ Perplexity รวมถึง Azure AI Foundry, Amazon Bedrock และโมเดลที่โฮสต์เอง

คุณเลือกโมเดลด้วย string เช่น:

Agent('anthropic:claude-sonnet-4-6')
Agent('openai:gpt-4o')
Enter fullscreen mode Exit fullscreen mode

การสลับ provider มักเป็นการเปลี่ยนเพียงบรรทัดเดียว

PydanticAI ต่างจาก LangChain หรือ LangGraph อย่างไร?

PydanticAI โฟกัส type safety: structured output ที่ validate แล้ว และ tool arguments ที่ validate จาก type hints และ Pydantic model

LangGraph โฟกัส graph-based orchestration และ stateful workflow สำหรับงานหลายขั้นตอนที่มี branch ชัดเจน

ถ้าปัญหาหลักของคุณคือ “ต้องมั่นใจว่าเอาต์พุตตรง schema” ให้เริ่มจาก PydanticAI แต่ถ้าปัญหาหลักคือ “ต้องควบคุม state machine หลาย node” เฟรมเวิร์กแบบ graph อาจเหมาะกว่า

จำเป็นต้องรู้ Pydantic ก่อนใช้ PydanticAI หรือไม่?

ไม่จำเป็น แต่ช่วยมาก พื้นฐานที่ต้องรู้คือการประกาศ data model ด้วย BaseModel:

from pydantic import BaseModel

class User(BaseModel):
    id: int
    email: str
Enter fullscreen mode Exit fullscreen mode

จากนั้น PydanticAI จะใช้ model เหล่านี้เป็น schema สำหรับ output และ validation ถ้าคุณเคยใช้ FastAPI หรือ Python สำหรับการทดสอบ API มาก่อน แนวคิดจะคุ้นเคยมาก

บทสรุป

PydanticAI ทำให้การสร้างเอเจนต์ Python ใช้งานจริงได้ปลอดภัยขึ้น โดยให้คุณประกาศ schema ของเอาต์พุตและ tool arguments แล้วปล่อยให้เฟรมเวิร์ก validate และ retry อัตโนมัติ เหมาะกับงาน production ที่ผลลัพธ์จาก LLM ต้องไหลเข้าโค้ดจริงและต้องเชื่อถือรูปแบบข้อมูลได้

ไม่ว่าคุณจะเลือกเฟรมเวิร์กใด API ที่อยู่เบื้องหลังเอเจนต์ยังต้องถูกทดสอบเสมอ ใช้ Apidog เพื่อ mock LLM หรือ tool endpoint, ตรวจ response schema และจัดการ environment แยกตาม local, staging และ CI เพื่อให้เอเจนต์ทำงานบน API surface ที่คุณตรวจสอบแล้ว

Top comments (0)