展开本页目录
开始前准备什么
- Python 3.13+ 与独立练习目录;默认离线重放不需要 Key。
- 发起新请求时使用自己的 apizt Key;先核对当前模型权限和价格,Key 不写入教材。
- 材料为原创合成样例;相关第三方项目仅作方法参考,真实执行范围以本页记录为准。
- 核对输入
- 保存响应
- 执行本地处理
- 验收文件和负例
原始输入、真实请求与响应、业务脚本、正反例检查及已生成的结果文件;不含 Key。
1. 准备这份输入,先确定不能猜的字段
生成报告后正确处理附件名称,保存原始内容并核对哈希。先将下面的原创合成材料保存为 input.json;不要一开始接正式客户资料。
本例与已有教程的区别:既有文章及本批未覆盖Content-Disposition中文附件名;与正文UTF-8解码、文件交接清单不同。
input.json(较长时显示节选,完整文件在资料包)
{
"store_A": 12,
"store_B": 8,
"download_name": "门店日报.md"
}2. 发送一次小请求,保留原始响应
下载并解压资料包,按 README 创建独立 Python 环境。python run.py 默认仅离线复核已保存回执;显式运行 python run.py --live 才发起新请求并可能计费。
模型阶段使用下面的任务约束。若存在预处理,prepared-input.json 是去重、分页收集或过滤后的真实输入;完整原始材料仍保留。识图任务发送实际 JPEG,不把人工真值放入提示词。
对应任务的请求参数说明;完整实际 request-N.json 见资料包
{
"model": "gpt-4.1-mini",
"messages": [
{
"role": "system",
"content": "只处理给定的虚构演示材料。只输出JSON,report字符串。写一段简短中文Markdown报告,保留门店A=12、门店B=8的演示数据。"
},
{
"role": "user",
"content": "{\n \"store_A\": 12,\n \"store_B\": 8,\n \"download_name\": \"门店日报.md\"\n}"
}
],
"temperature": 0,
"max_tokens": 1024,
"provider": {
"sort": "success_rate"
},
"response_format": {
"type": "json_object"
}
}3. 执行本例的本地处理,模型字段还要再验算
以下节选来自这次实际执行的 verify-task.py 分支。完整函数和辅助方法均在资料包;运行 python run.py 会使用原始回执重放这段业务操作,而不是让模型自己宣布成功。
实际HTTP响应优先采用UTF-8中文filename*;保存后的SHA256与真实API报告内容一致;同名文件不被覆盖;文件名解析:report.md;文件名解析:a+b.md;文件名解析:a b.md;文件名解析:semi;colon.md;非法文件名反例被拒绝;非法文件名反例被拒绝;非法文件名反例被拒绝;非法文件名反例被拒绝
verify-task.py · download-name 分支节选,需在完整脚本上下文运行
import importlib.util
from urllib.parse import quote
spec = importlib.util.spec_from_file_location('download_name', Path(__file__).resolve().parent / 'download-name.py')
helper = importlib.util.module_from_spec(spec)
spec.loader.exec_module(helper)
header = 'attachment; filename="report.md"; filename*=UTF-8\'\'' + quote(data['download_name'])
body = output['report'].encode('utf-8')
class Handler(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.send_header('Content-Disposition', header)
self.send_header('Content-Type', 'text/markdown; charset=utf-8')
self.send_header('Content-Length', str(len(body)))
self.end_headers()
self.wfile.write(body)
def log_message(self, *_):
pass
server = ThreadingHTTPServer(('127.0.0.1', 0), Handler)
thread = threading.Thread(target=server.serve_forever, daemon=True)
thread.start()
try:
with urllib.request.urlopen(f'http://127.0.0.1:{server.server_port}/report', timeout=5) as response:
filename = helper.attachment_name(response.headers['Content-Disposition'])
downloaded = response.read()
check('实际HTTP响应优先采用UTF-8中文filename*', filename == '门店日报.md')
with tempfile.TemporaryDirectory() as directory:
saved = helper.save_new(directory, filename, downloaded)
check('保存后的SHA256与真实API报告内容一致', hashlib.sha256(saved.read_bytes()).digest() == hashlib.sha256(body).digest())
try:
helper.save_new(directory, filename, b'do not overwrite')
check('同名文件不被覆盖', False)
except FileExistsError:
check('同名文件不被覆盖', saved.read_bytes() == body)
valid = [('attachment; filename="report.md"', 'report.md'), ("attachment; filename*=UTF-8''a+b.md", 'a+b.md'), ("attachment; filename*=UTF-8''a%20b.md", 'a b.md'), ('attachment; filename="semi;colon.md"', 'semi;colon.md')]
for value, expected_name in valid:
check('文件名解析:' + expected_name, helper.attachment_name(value) == expected_name)
for value in ["attachment; filename*=UTF-8''bad%ZZ.md", 'attachment; filename="a"; filename="b"', "attachment; filename*=UTF-8''..%2Fescape.md", "attachment; filename*=UTF-8''bad%0A.md"]:
try:
helper.attachment_name(value)
check('非法文件名反例被拒绝', False, value)
except (ValueError, UnicodeDecodeError):
check('非法文件名反例被拒绝', True, value)
(folder / 'report.md').write_bytes(body)
result = {'download_name': filename, 'content_sha256': hashlib.sha256(body).hexdigest(), 'bytes': len(body), 'report': output['report']}
finally:
server.shutdown()
server.server_close()
thread.join(timeout=5)4. 查看真实结果、文件与验收记录
本次 16/16 项通过。模型返回与最终业务结果分开保存;以下是本地处理后的 result.json。
最后一次实测时间:2026-10-24T15:37:44.357989+00:00;HTTP 200;请求型号 gpt-4.1-mini;返回型号 gpt-4.1-mini;本次返回用量 132。中断或超时不会补造用量,多个尝试不合并成一次成功。
实际产物:checks.json、report.md、result.json。
| 检查项 | 本次结果 |
|---|---|
| 真实 apizt 响应 HTTP 200 | 通过 |
| 原始响应 content 可直接解析 JSON | 通过 |
| 事实检查:report | 通过 |
| 事实检查:report | 通过 |
| 明确错误的本地反例被验收规则拒绝 | 通过 |
| 实际HTTP响应优先采用UTF-8中文filename* | 通过 |
| 保存后的SHA256与真实API报告内容一致 | 通过 |
| 同名文件不被覆盖 | 通过 |
| 文件名解析:report.md | 通过 |
| 文件名解析:a+b.md | 通过 |
| 文件名解析:a b.md | 通过 |
| 文件名解析:semi;colon.md | 通过 |
| 非法文件名反例被拒绝 | 通过 |
| 非法文件名反例被拒绝 | 通过 |
| 非法文件名反例被拒绝 | 通过 |
| 非法文件名反例被拒绝 | 通过 |
- 检查项
- 真实 apizt 响应 HTTP 200
- 本次结果
- 通过
- 检查项
- 原始响应 content 可直接解析 JSON
- 本次结果
- 通过
- 检查项
- 事实检查:report
- 本次结果
- 通过
- 检查项
- 事实检查:report
- 本次结果
- 通过
- 检查项
- 明确错误的本地反例被验收规则拒绝
- 本次结果
- 通过
- 检查项
- 实际HTTP响应优先采用UTF-8中文filename*
- 本次结果
- 通过
- 检查项
- 保存后的SHA256与真实API报告内容一致
- 本次结果
- 通过
- 检查项
- 同名文件不被覆盖
- 本次结果
- 通过
- 检查项
- 文件名解析:report.md
- 本次结果
- 通过
- 检查项
- 文件名解析:a+b.md
- 本次结果
- 通过
- 检查项
- 文件名解析:a b.md
- 本次结果
- 通过
- 检查项
- 文件名解析:semi;colon.md
- 本次结果
- 通过
- 检查项
- 非法文件名反例被拒绝
- 本次结果
- 通过
- 检查项
- 非法文件名反例被拒绝
- 本次结果
- 通过
- 检查项
- 非法文件名反例被拒绝
- 本次结果
- 通过
- 检查项
- 非法文件名反例被拒绝
- 本次结果
- 通过
verified/result.json(节选)
{
"download_name": "门店日报.md",
"content_sha256": "cb0d6c20e95d94945435cb4cd39fb68305e8830b38e13e9eef1c448b7c1c075a",
"bytes": 147,
"report": "# 门店日报报告\n\n- 门店A销售数量:12\n- 门店B销售数量:8\n\n门店A的销售表现优于门店B,建议继续保持现有策略。"
}5. 换自己的材料时,先检查失败分支
本例只验收下载文件名与内容哈希;模型报告中的经营建议没有因果依据,不作为业务建议采用。
本例是小样验证;替换输入后必须重新检查字段、事实和实际费用。
只把本篇标注的任务作为本次验收范围。第三方软件、未测模型、工具调用能力和真实用户数据都需要另行验证;没有调用视频生成模型。
- 实际HTTP响应优先采用UTF-8中文filename*
- 保存后的SHA256与真实API报告内容一致
- 同名文件不被覆盖
- 文件名解析:report.md
- 文件名解析:a+b.md
- 文件名解析:a b.md
解压目录中运行;第一条离线,第二条显式发起新请求
python run.py
# 安全设置自己的 tokenba_API_KEY 后,才执行下面这一条
python run.py --live怎样确认已经完成
- 真实 apizt 响应 HTTP 200
- 原始响应 content 可直接解析 JSON
- 事实检查:report
- 事实检查:report
- 明确错误的本地反例被验收规则拒绝
- 实际HTTP响应优先采用UTF-8中文filename*
- 保存后的SHA256与真实API报告内容一致
- 同名文件不被覆盖
- 文件名解析:report.md
- 文件名解析:a+b.md
- 文件名解析:a b.md
- 文件名解析:semi;colon.md
- 非法文件名反例被拒绝
- 非法文件名反例被拒绝
- 非法文件名反例被拒绝
- 非法文件名反例被拒绝
常见问题
Python AI 报告下载只看 HTTP200 就完成了吗?
还需要按本页独立规则检查事实、缺失项及最终文件。模型阶段成功与本地工作流成功分别记录。
可以不登录其他平台运行本例吗?
可以。本例使用 apizt API 和本地 Python 脚本;离线复核也无需 API Key。第三方软件的原生 UI、插件和账号权限不在本次验收范围。
更换输入后还能沿用本页的通过结果吗?
不能。原始事实断言只适用于本页合成材料。替换输入后必须同步调整 expected、业务规则与负例,再检查输出。


