1
0

feat: 完善流式测试覆盖并精简用例

- 提取共享定义(tool_weather, image_url, json_schema_math)到功能块前
- 流式用例精简为代表子集:核心 6-8 个 + 扩展各 1-2 个 + 高级参数代表
- OpenAI: 15 个流式用例(核心 8 + vision/tools/logprobs/json_schema + 高级参数)
- Anthropic: 11 个流式用例(核心 6 + vision/tools/thinking + 高级参数)
- 更新 README:新增流式测试覆盖原则、parse_sse_events 函数说明
This commit is contained in:
2026-04-21 17:18:35 +08:00
parent 6e11ada42c
commit 44d6af026a
3 changed files with 340 additions and 124 deletions

View File

@@ -318,6 +318,24 @@ def main():
models_url = f"{base_url}/v1/models"
count_tokens_url = f"{base_url}/v1/messages/count_tokens"
# ---- 共享定义(供流式和非流式用例共同使用)----
image_url = (
"https://upload.wikimedia.org/wikipedia/commons/thumb/d/dd/"
"Gfp-wisconsin-madison-the-nature-boardwalk.jpg/"
"2560px-Gfp-wisconsin-madison-the-nature-boardwalk.jpg"
)
tool_weather = {
"name": "get_weather",
"description": "获取指定城市的天气",
"input_schema": {
"type": "object",
"properties": {
"location": {"type": "string", "description": "城市名称"}
},
"required": ["location"]
}
}
# --- 收集测试用例 ---
cases: List[TestCase] = []
@@ -744,9 +762,7 @@ def main():
{"type": "text", "text": "用一个词描述这张图"},
{"type": "image", "source": {
"type": "url",
"url": "https://upload.wikimedia.org/wikipedia/commons/thumb/d/dd/"
"Gfp-wisconsin-madison-the-nature-boardwalk.jpg/"
"2560px-Gfp-wisconsin-madison-the-nature-boardwalk.jpg"
"url": image_url
}}
]}]
},
@@ -755,64 +771,120 @@ def main():
# ==== --stream ====
if args.stream:
# 核心用例
cases.append(TestCase(
desc="基本流式 (--stream)",
desc="流式基本对话",
method="POST",
url=messages_url,
headers=headers,
body={
"model": model,
"max_tokens": 5,
"stream": True,
"messages": [{"role": "user", "content": "Hi"}]
},
body={"model": model, "max_tokens": 5, "stream": True, "messages": [{"role": "user", "content": "Hi"}]},
stream=True,
validator=validate_anthropic_streaming_response
))
cases.append(TestCase(
desc="流式 + system prompt (--stream)",
desc="流式 + system prompt",
method="POST",
url=messages_url,
headers=headers,
body={
"model": model,
"max_tokens": 5,
"stream": True,
"system": "Reply in one word.",
"messages": [{"role": "user", "content": "1+1="}]
},
body={"model": model, "max_tokens": 5, "stream": True, "system": "有帮助的助手", "messages": [{"role": "user", "content": "Hi"}]},
stream=True,
validator=validate_anthropic_streaming_response
))
cases.append(TestCase(
desc="流式 + stop_sequences (--stream)",
desc="流式多轮对话",
method="POST",
url=messages_url,
headers=headers,
body={
"model": model,
"max_tokens": 20,
"stream": True,
"stop_sequences": ["5"],
"messages": [{"role": "user", "content": "数数: 1,2,3,"}]
},
body={"model": model, "max_tokens": 5, "stream": True, "messages": [{"role": "user", "content": "Hi"}, {"role": "assistant", "content": "Hello"}, {"role": "user", "content": "1+1"}]},
stream=True,
validator=validate_anthropic_streaming_response
))
cases.append(TestCase(
desc="流式 temperature + top_p",
method="POST",
url=messages_url,
headers=headers,
body={"model": model, "max_tokens": 5, "stream": True, "temperature": 0.5, "top_p": 0.9, "messages": [{"role": "user", "content": "Hi"}]},
stream=True,
validator=validate_anthropic_streaming_response
))
cases.append(TestCase(
desc="流式 max_tokens",
method="POST",
url=messages_url,
headers=headers,
body={"model": model, "max_tokens": 3, "stream": True, "messages": [{"role": "user", "content": "Hi"}]},
stream=True,
validator=validate_anthropic_streaming_response
))
cases.append(TestCase(
desc="流式 stop_sequences",
method="POST",
url=messages_url,
headers=headers,
body={"model": model, "max_tokens": 10, "stream": True, "stop_sequences": ["5"], "messages": [{"role": "user", "content": "数数: 1,2,3,"}]},
stream=True,
validator=validate_anthropic_streaming_response
))
# 流式 + vision
if args.vision:
cases.append(TestCase(
desc="流式图片输入",
method="POST",
url=messages_url,
headers=headers,
body={"model": model, "max_tokens": 10, "stream": True, "messages": [{"role": "user", "content": [{"type": "text", "text": "描述图"}, {"type": "image", "source": {"type": "url", "url": image_url}}]}]},
stream=True,
validator=validate_anthropic_streaming_response
))
# 流式 + tools
if args.tools:
cases.append(TestCase(
desc="流式工具调用 auto",
method="POST",
url=messages_url,
headers=headers,
body={"model": model, "max_tokens": 50, "stream": True, "tools": [tool_weather], "tool_choice": {"type": "auto"}, "messages": [{"role": "user", "content": "北京天气?"}]},
stream=True,
validator=validate_anthropic_streaming_response
))
cases.append(TestCase(
desc="流式多轮工具调用",
method="POST",
url=messages_url,
headers=headers,
body={"model": model, "max_tokens": 20, "stream": True, "tools": [tool_weather], "messages": [{"role": "user", "content": "北京天气?"}, {"role": "assistant", "content": [{"type": "tool_use", "id": "toolu_001", "name": "get_weather", "input": {"location": "Beijing"}}]}, {"role": "user", "content": [{"type": "tool_result", "tool_use_id": "toolu_001", "content": '{"temp": 22}'}]}]},
stream=True,
validator=validate_anthropic_streaming_response
))
# 流式 + thinking
if args.thinking:
cases.append(TestCase(
desc="流式扩展思维",
method="POST",
url=messages_url,
headers=headers,
body={"model": model, "max_tokens": 100, "stream": True, "thinking": {"type": "enabled", "budget_tokens": 50}, "messages": [{"role": "user", "content": "1+1=?"}]},
stream=True,
validator=validate_anthropic_streaming_response
))
# 流式高级参数
cases.append(TestCase(
desc="流式 service_tier: auto",
method="POST",
url=messages_url,
headers=headers,
body={"model": model, "max_tokens": 5, "stream": True, "service_tier": "auto", "messages": [{"role": "user", "content": "Hi"}]},
stream=True,
validator=validate_anthropic_streaming_response
))
# ==== --tools ====
if args.tools:
tool_weather = {
"name": "get_weather",
"description": "获取指定城市的天气",
"input_schema": {
"type": "object",
"properties": {
"location": {"type": "string", "description": "城市名称"}
},
"required": ["location"]
}
}
cases.append(TestCase(
desc="工具调用 tool_choice: auto (--tools)",
method="POST",
@@ -982,36 +1054,6 @@ def main():
validator=validate_anthropic_messages_response
))
# ==== --stream + --tools 组合 ====
if args.stream and args.tools:
tool_weather_stream = {
"name": "get_weather",
"description": "获取指定城市的天气",
"input_schema": {
"type": "object",
"properties": {
"location": {"type": "string", "description": "城市名称"}
},
"required": ["location"]
}
}
cases.append(TestCase(
desc="流式工具调用 (--stream --tools)",
method="POST",
url=messages_url,
headers=headers,
body={
"model": model,
"max_tokens": 50,
"stream": True,
"tools": [tool_weather_stream],
"tool_choice": {"type": "auto"},
"messages": [{"role": "user", "content": "北京天气怎么样?"}]
},
stream=True,
validator=validate_anthropic_streaming_response
))
# ==== 高级参数测试 ====
# cache_control: 缓存控制
cases.append(TestCase(