Pydantic AI
通过 TwexAPI MCP 构建 Pydantic AI Twitter API AI Agent,实现类型化推文搜索、资料查询、粉丝列表与经审核的 X 写操作。
通过 TwexAPI 的 MCP 服务器构建 Pydantic AI Twitter API AI Agent。搜索推文、查看资料,并用 Pydantic 模型校验每条 durable handoff。审核每条拟议发帖、回复、点赞、关注或私信。
为何将 Pydantic AI 与 TwexAPI 搭配使用?
Pydantic AI 将模型工具调用与类型化 Python 输出结合。TwexAPI 通过 MCP 工具 explore 与 twexapi_request 提供 Twitter API 路由。
| 边界 | Pydantic AI 控制 | Twitter AI Agent收益 |
|---|---|---|
| MCP 连接 | MCPServerStreamableHTTP |
凭证保留在进程内 |
| 最终响应 | Pydantic output_type |
拒绝畸形推文行与游标 |
| 写操作 | 人工审核步骤 | 发帖、回复或关注前暂停 |
| 连接生命周期 | async with agent |
相关调用复用同一 MCP 会话 |
推文搜索或资料 enrichment 各用一个类型化AI Agent,保持专注。
前置条件
- Python 3.10 或更高版本
- TwexAPI API 密钥
- 支持工具调用的 Pydantic AI 兼容模型
- 写操作所需的 Twitter cookie 或
auth_token
安装
python -m pip install "pydantic-ai[mcp]" python-dotenv
将密钥存放在源码控制之外。
export TWEXAPI_API_KEY="YOUR_API_KEY"
export ANTHROPIC_API_KEY="YOUR_ANTHROPIC_KEY"
构建类型化推文搜索AI Agent
创建AI Agent前先定义最终 handoff。Pydantic AI 按该 schema 校验模型输出。
import asyncio
import os
from pathlib import Path
from typing import Literal
from dotenv import load_dotenv
from pydantic import BaseModel
from pydantic_ai import Agent
from pydantic_ai.mcp import MCPServerStreamableHTTP
class TweetRow(BaseModel):
tweet_id: str
text: str
author_username: str | None = None
created_at: str | None = None
url: str | None = None
class TweetSearchHandoff(BaseModel):
query: str
route_used: str
tweets: list[TweetRow]
has_more: bool
next_cursor: str | None = None
stop_reason: Literal["complete", "requested_limit", "cursor_stalled"]
async def main() -> None:
load_dotenv()
server = MCPServerStreamableHTTP(
"https://api.twexapi.io/mcp",
headers={"x-api-key": os.environ["TWEXAPI_API_KEY"]},
)
agent = Agent(
"anthropic:claude-sonnet-4-20250514",
toolsets=[server],
output_type=TweetSearchHandoff,
instructions=(
"Use TwexAPI MCP for Twitter API requests. Call explore before twexapi_request. "
"Preserve exact IDs and cursors. Never invent missing tweet fields. "
"Ask for confirmation before read_only: false actions."
),
)
result = await agent.run(
"Search 25 recent tweets about Pydantic AI MCP. "
"Return the query, route, tweet rows, cursor state, "
"and an explicit stop reason."
)
Path("twexapi-pydantic-ai-handoff.json").write_text(
result.output.model_dump_json(indent=2),
encoding="utf-8",
)
asyncio.run(main())
AI Agent可发现 explore 与 twexapi_request。不知路由或参数形状时先调用 explore。
存储前校验字段
输出模型中保持以下源字段不变:
- 推文行:
tweet_id、text、author_username、created_at、url - 资料行:
user_id、username、name、description、粉丝数 - 分页状态:
has_more、next_cursor或语言特定游标名 - 写回执:路由名、返回 tweet ID、确认状态
切勿将大 ID 转为浮点。仅在输出模型中将源 ID 映射为 tweet_id 或 user_id。
has_more 仍为 true 时继续空页。无游标或服务器重复游标时停止。返回 cursor_stalled 及已收集行数。
构建类型化 handoff
推文高级搜索
存储查询、路由、tweet ID、作者、URL、has_more、next_cursor 与停止原因。
查询用户资料
存储 user_id、username、name、description 与粉丝数。
粉丝列表分页
存储源用户名、粉丝行与游标检查点。
写入操作 (发推/点赞/关注)
存储路由、预览文本、cookie 要求与审批记录。
API 密钥勿写入AI Agent输出。见 Agent MCP Handoff。
复用 MCP 连接
多次运行应共享连接时,包装相关调用。
async def collect_two_search_pages(agent: Agent) -> None:
async with agent:
first_page = await agent.run(
"Search 25 tweets about Pydantic AI MCP. Preserve the next cursor."
)
cursor = first_page.output.next_cursor
if not first_page.output.has_more or cursor is None:
return
second_page = await agent.run(
f"Continue tweet search for {first_page.output.query!r}. "
f"Use explore, then twexapi_request with cursor {cursor!r}."
)
_ = second_page
X 操作前要求审批
只读AI Agent可自动搜索推文。具备写能力的AI Agent在每次 X 操作前需人工决策。
class WritePlan(BaseModel):
action: str
endpoint: str
preview_text: str
requires_human_confirmation: bool = True
调用 read_only: false 路由前停止AI Agent。用 CLI --dry-run 预览载荷,审批后通过 REST 或 Python SDK 执行。
错误处理
| 状态 | Pydantic AI 决策 |
|---|---|
400 |
重试前修正请求 |
401 |
停止并更换凭证 |
403 |
报告访问或额度问题 |
429 |
退避并保留游标 |
5xx |
对有界退避重试安全读取 |
超时后切勿在未检查返回状态的情况下重建 pending 写操作。
选择 Pydantic AI MCP 或 REST
| 需求 | 选择 | 原因 |
|---|---|---|
| 模型选择推文或资料操作 | Pydantic AI MCP | AI Agent用 explore 发现路由 |
| 应用代码调用已知单一路由 | Python SDK | 请求保持确定性 |
| 人工须审核 X 操作 | Pydantic AI MCP + 手动 REST | 执行前暂停 |
| 定时导出无需模型 | Prefect 或 REST | 无需模型决策 |
包版本
| 包 | 支持范围 |
|---|---|
| Python | >=3.10 |
pydantic-ai |
>=0.8 |
pydantic |
>=2.7 |