首页
/ screenshot-to-code 后端开发实战:Poetry 工具链、Pytest 测试与 Prompt 摘要调试

screenshot-to-code 后端开发实战:Poetry 工具链、Pytest 测试与 Prompt 摘要调试

2026-09-03 17:16:26作者:何将鹤

本文围绕 screenshot-to-code 仓库 backend/README.md 中给出的三条后端开发工作流展开:用 poetry run pyright 运行类型检查、用 poetry run pytest 运行测试,以及用 utils.py 里的 print_prompt_summary 快速可视化 LLM prompt。读完本文,你可以在本仓库的后端环境中完整跑起类型检查与测试套件,并能对发送给模型的 prompt 消息列表做摘要化检视,定位截图转代码流程中的提示词组装问题。

后端技术栈与环境基线

在动手之前,先明确这套开发工作流所依赖的环境。后端是 FastAPI 应用,包管理使用 Poetry,相关声明集中在 backend/pyproject.toml

  • Python 版本约束为 ^3.10,核心依赖包括 fastapiuvicornopenaianthropicgoogle-genaiplaywright 等;
  • 开发依赖组中声明了 pytest = "^7.4.3"pyright = "^1.1.352"pytest-asyncio = "^0.21",这正是 README 中两条 poetry run 命令背后可调用的工具;
  • 项目声明 package-mode = false,即 Poetry 只负责依赖管理与虚拟环境,后端代码本身不作为可安装包分发。

应用入口在 backend/main.py:它先调用 load_dotenv() 加载环境变量,再创建 FastAPI 实例并挂载 generate_codescreenshotevals 等路由。backend/config.py 则集中读取 OPENAI_API_KEYANTHROPIC_API_KEYGEMINI_API_KEYREPLICATE_API_KEY 等环境变量,并定义 IS_DEBUG_ENABLEDDEBUG_DIR 等调试开关——这些变量通常写入 backend/.env(仓库 README 的 Getting Started 章节有完整的环境变量配置示例)。

运行类型检查:poetry run pyright

backend/README.md 的第一条命令是:

poetry run pyright

它通过 Poetry 虚拟环境中安装的 pyright 对后端 Python 代码做静态类型检查。检查行为由 backend/pyrightconfig.json 控制,内容简短但信息量完整:

{
  "exclude": ["image_generation.py"],
  "typeCheckingMode": "basic",
  "reportMissingTypeStubs": "none",
  "reportUnknownVariableType": "warning"
}

逐项解读:

  • "typeCheckingMode": "basic":采用基础检查级别,只报告高置信度的类型错误,而不是 strict 模式下的全量诊断,适合以动效为主、快速迭代的应用型项目;
  • "exclude": ["image_generation.py"]:显式排除该文件,从源码结构看它是较早引入的图像生成模块,被排除在类型检查之外;
  • "reportMissingTypeStubs": "none":对第三方库缺少类型存根(stub)的情况不报错,避免 moviepypillow-heif 这类依赖的 stub 缺失干扰开发流;
  • "reportUnknownVariableType": "warning":允许 Unknown 变量存在但给出警告,属于一种渐进式收紧类型质量的策略。

实际使用时,建议先完成 poetry install 并进入后端目录(或激活 Poetry 环境)再执行该命令;命令在 backend 目录下执行时,pyright 会自动读取同级的 pyrightconfig.json

运行测试:poetry run pytest 与测试约定

README 的第二条命令是:

poetry run pytest

测试的执行规则定义在 backend/pytest.ini

[pytest]
testpaths = tests
python_files = test_*.py
python_classes = Test*
python_functions = test_*
addopts = -v --tb=short
asyncio_mode = auto

这份配置约定了:

  • 测试只从 backend/tests 目录收集(testpaths = tests),该目录下有 40 余个测试文件,覆盖 agent 引擎(test_agent_engine.py)、各家模型 provider(test_anthropic_provider_config.pytest_gemini_provider_session.pytest_openai_provider_session.py)、工具运行时(test_agent_tool_runtime.py)、资产提取(test_asset_extraction.py)、评测系统(test_eval_runner.pytest_eval_sessions.py)等模块;
  • addopts = -v --tb=short:默认以详细模式运行并输出精简的失败堆栈,无需每次手动传参;
  • asyncio_mode = auto:配合 pytest-asyncio,让 async def test_* 用例被自动识别为异步测试,无需逐个加 @pytest.mark.asyncio 标记。

例如针对 prompt 摘要功能的测试 backend/tests/test_prompt_summary.py 就是一个典型样例:它构造包含纯文本和 text/image_url 混合 content 的消息列表,断言 format_prompt_summary 的输出中包含 "SYSTEM: lorem ipsum""[2 images]",并捕获 stdout 验证 print_prompt_summary 输出的方框字符与标题。运行 poetry run pytest 时,这一整组用例都会按上述约定被收集并执行。

Prompt 摘要工具:print_prompt_summary 的用法与实现

backend/README.md 的核心内容是“Prompt Summary”一节:

Use print_prompt_summary from utils.py to quickly visualize prompts:

from utils import print_prompt_summary
print_prompt_summary(prompt_messages)

这个工具面向的场景很具体:screenshot-to-code 后端在生成代码前会把系统提示词、用户输入、截图(以 image_url 形式内嵌)等组装成 List[ChatCompletionMessageParam] 消息列表,列表往往很长且含大量 base64 数据,直接打印既冗长又看不清结构。print_prompt_summary 就是为此设计的“快速检视”入口。

其实现位于 backend/utils.py,核心逻辑分两层:

  1. 摘要格式化format_prompt_summary):遍历每条消息,读取 role;若 content 是列表,则累加所有 text 块、统计 image_url 块的数量;若 content 是字符串则直接取用。默认 truncate=True 时,超过 40 个字符的文本会被截断为前 40 字符加省略号,图像则以 + [N images] 后缀标注。
  2. 方框打印print_prompt_summary):根据各行长度计算框宽(截断模式下上限 80 列,完整模式下上限 120 列,下限 20 列),对超长行按词换行,最终输出带 ┌─…─┐ 边框、居中标题为 PROMPT SUMMARY 的等宽框体。

因此一段实际输出形如:

┌──────────────────────────────────────────────┐
│                 PROMPT SUMMARY               │
├──────────────────────────────────────────────┤
│ SYSTEM: You are an expert web developer...   │
│ USER: Convert this screenshot to HTML + [1   │
│ images]                                      │
└──────────────────────────────────────────────┘

utils.py 中还提供了与摘要互补的两个工具,调试 prompt 时可以按信息粒度选用:

  • pprint_prompt:深拷贝消息列表后经 truncate_data_strings 把每个长字符串截为 40 字符(附 ... (N chars)),再以 indent=4 打印 JSON,适合查看消息结构(但比摘要更原始);
  • print_prompt_preview(配合 format_prompt_preview):按消息顺序编号输出,每条消息预览默认最多 280 字符,超出的部分保留“头部一半 + 尾部四分之一”并以 ... [collapsed N chars] ... 标记,媒体内容统一标注为 [N media],适合在不打印 base64 的前提下看清每条提示词的要点。

调试建议:在 llm.py 或各 provider 的调用点附近临时插入 print_prompt_summary(messages),确认角色顺序、文本截断位置与图像数量是否符合预期;若要核对完整提示词内容,改用 print_prompt_preview 或直接查看 PROMPT_REPORTS_ENABLED 开启后的 /evals/prompt-reports 报告(该开关的语义见 backend/config.py)。

小结

backend/README.md 虽然简短,但它定义了本仓库后端开发的三件基础武器:poetry run pyright(配合 backend/pyrightconfig.json 的 basic 模式做类型把关)、poetry run pytest(配合 backend/pytest.ini 的自动异步模式与统一收集规则跑全量测试),以及 backend/utils.py 中的 prompt 摘要工具链(print_prompt_summary / print_prompt_preview / pprint_prompt)。把这三者串起来,就构成了在 screenshot-to-code 后端中“改代码 → 查类型 → 跑测试 → 检视 prompt”的完整调试闭环。

登录后查看全文
热门项目推荐
相关项目推荐