一个 Agent 类
一个 protocol 字段
注册表把 protocol 字符串映射到 transport 实现。加新 provider = 一个 transport 类 + 一次 register_protocol(...)。
class Reviewer(Agent):
protocol = "anthropic" # 一行切TANGYUANAI · QUICK API · SIMPLE AGENTS
一个轻量、模块化的 Agent 框架。
一个 Agent 类、一个 protocol 字段——快速对接 OpenAI / Anthropic / 自家网关,几行代码构建 Agent。
# 定义 Agent —— 一个类,一个 protocol 字段
import tangyuanAI
@tangyuanAI.template_agent(
"weather", description="天气查询助手")
class WeatherAgent(tangyuanAI.Agent):
prompt = "你是天气助手"
protocol = "openai" # 一行切协议
model_name = "gpt-5"
tangyuanAI.activate_template("weather")
tangyuanAI.agent_list["weather"].conversation(
"北京今天天气?")
# → "北京今天晴,温度 25°C"THE PROBLEM
OpenAI 要 role="tool" 块;Anthropic 要 tool_use_id 回声;Responses 要 input 列表;你公司机房的网关,又讲另一种话。写死一个 SDK,就把自己锁死在一个 provider。
# 原生 function-calling
messages.append({
"role": "tool",
"tool_call_id": call.id,
"content": result
})# tool_result 内容块 + 回声
{
"type": "tool_result",
"tool_use_id": block.id, # 必须回
"content": result,
"is_error": False
}# typed items 进 input 列表
"input": [
{"type": "message", "role": "user",
"content": [{"type": "input_text",
"text": msg}]}
]# 只有你们自己人知道…
"wrapper": {"inner": "payload"},
"route": "/api/gw/v3",
"vendor": "weird-warehouse"
# 三个 URL 都要改如果每对接一个 API 都要重写一遍循环,
那不是在做 Agent,是在做集成。
THE PITCH
tangyuanAI 把 LLM API 的差异收拢到一个地方。目的不是功能堆叠——而是让你几分钟对接新 API,几行代码构建 Agent。
protocol 字段注册表把 protocol 字符串映射到 transport 实现。加新 provider = 一个 transport 类 + 一次 register_protocol(...)。
class Reviewer(Agent):
protocol = "anthropic" # 一行切原生 function-calling 也好,stream 里塞 XML 也好,框架都桥接好。ACL、Pydantic 校验、单调用超时全部内置。
def get_weather(city: str) -> str:装饰器即配置继承 Agent + 类属性 = 一种 Agent。@template_agent 注册到池,activate_template("name") 一行激活。同一份代码,换 provider = 改一个字段。
@tangyuanAI.template_agent("writer",
description="写作助手")
class Writer(tangyuanAI.BaseAgent):
protocol = "openai"
model_name = "gpt-5"ARCHITECTURE
QUICKSTART
# 1. 装包并设置密钥
$ uv add tangyuanAI
$ export API_KEY="sk-…"
# 2. 注册工具 —— 一个函数 = 一份 JSON Schema
@tangyuanAI.tool_registry.register_tool(
description="uv add查询某城市天气(演示用返回假数据)",
parameters={"type": "object",
"properties": {"city": {"type": "string"}},
"required": ["city"]},
)
def get_weather(city: str) -> str:
return f"{city} 今天晴,温度 25°C"
# 3. 定义 Agent
@tangyuanAI.template_agent(
"weather", uuid="weather-uuid-1",
description="天气查询助手",
)
class WeatherAgent(tangyuanAI.BaseAgent):
prompt = "你是天气助手,用 get_weather 工具回答问题"
api_provider = "https://api.openai.com/v1/chat/completions"
model_name = "gpt-5"
api_key = "sk-…"
# 4. 运行
if __name__ == "__main__":
tangyuanAI.activate_template("weather")
tangyuanAI.agent_list["weather"].conversation(
"北京今天天气怎么样?")
# → "北京今天晴,温度 25°C"切协议?把 protocol 改成 "anthropic" 就完了。同一个类。
API INTEGRATION
# 自己接一个新 LLM API
client = httpx.AsyncClient(headers={
"Authorization": f"Bearer {key}"})
async def chat(messages):
payload = {"model": MODEL,
"messages": messages}
async for chunk in client.stream(
"POST", url, json=payload):
if chunk["type"] == "tool_call":
result = await run_tool(
chunk["name"], chunk["input"])
messages.append(
tool_msg(chunk["id"], result))
elif chunk["type"] == "error":
await backoff_retry()
# 鉴权 / 流式 / 工具桥接 / 重试…100+ 行,且只连通一家。
class AnyAgent(tangyuanAI.BaseAgent):
protocol = "openai" # ← 改这一行切 APIGET STARTED
一个 protocol 字段 = 对接一个 LLM API。