xsl e78ba3feef feat(report): LLM copy generation with mandatory post-validation and fallback
report_copy/v1 prompt(系统段零变量)+ 结构化 ReportCopy + 素材组装
(skipped 不进 prompt/超长裁剪)+ 贬损词表/一致性/绝对化三重校验 +
重试一次后降级规则直出模板(T-P3-10/11)。

- copy.py:ReportCopy(schema 宽进严出取舍见注释)/compose_prompt_material
  (ok 过滤+6000 字符裁剪,低优先级先丢、硬结论不丢,记录 dropped_keys)/
  render_fallback_copy 零 LLM 降级模板
- validation.py:PEJORATIVE_TERMS 35 词(源自合规 §3,初版内嵌注释)+
  一致性三规则(枚举同款含别名/色值在板内/建议句需规则支撑·宽松口径)+
  绝对化用语兜底
- copy_stage.py / validation_stage.py:任何出口 passed=true 或抛错,
  语义层重试一次(与网关解析层重试独立),仍违规降级模板并 fail-close 自证
- 单测 25 例(词表含变形/三规则正反/降级零违规)+ 集成 4 例
  (FakeProvider 全栈:干净通过/脏一次修正通过/持续脏降级且最终文案
  零贬损词——黄金断言);全量 529 单测 + 49 集成全绿

偏差说明:
1. prompts/report_copy/v1.txt 非新建——LLM 批次已放置初版(user 段变量
   为 {payload}),按本任务契约改写为 {dimensions_json} 并补内容红线
   (该文件任务文档明确归 T17,无与他人冲突)。
2. check_conclusion_consistency 按契约签名 (copy, dimensions) 之外增加
   可选 rule_hits 关键字参数:规则③的支撑判定需兼容命中内嵌在维度/
   顶层列表两种 T16 契约形态,缺省时不追责(宽松口径)。
3. 绝对化用语未按单字「最」拦截,取营销语境复合词(最好/最合适/第一/
   百分百等 17 词):单字会误杀「最近/最终」等中性词,红线范围不变。
4. 集成文件未挂 MEIDA_RUN_INTEGRATION skipif:用例为 FakeProvider 内存
   装配、不依赖真实 PG/Redis,按任务要求仍放 tests/integration/ 并带
   integration marker。
2026-08-14 22:09:09 +08:00

meida_backend · 美搭服务端

「美搭」智能穿搭美学助手的服务端。当前状态是工程地基 + 一条打通的纵向切片 (登录取 token → 配额预扣 → 真实调用 DeepSeek → 记成本 → 提交配额), 业务域大多只有目录与 README,见各 packages/*/README.md。

技术选型与分层依据见仓库外的《技术架构文档》《技术选型与调研报告》,本文只讲怎么跑起来。

快速开始

cp .env.example .env          # 填入 DEEPSEEK_API_KEY
make install                  # uv sync + 装 pre-commit
make up                       # PostgreSQL(pgvector) + Redis,端口 55432 / 56379
make migrate                  # 建表并创建 vector 扩展
make run                      # http://localhost:8000/api/v1/docs

验证真实链路(会产生真实 API 费用,是唯一花钱的入口):

make smoke

它会起依赖、迁移、拉起 API、发一次真实对话,然后把 ob_ai_call 的成本行与 bl_ledger 的配额流水打出来。跑通即证明「计量 + 配额 + 大模型」三者串通。

目录结构

目录 职责
apps/api HTTP 入口。只做鉴权、校验、幂等、配额、统一响应,不放业务规则
apps/worker Celery 长耗时任务入口
packages/domain 纯领域逻辑,不许 import 任何框架与 I/O
packages/llm 大模型网关:场景路由、Prompt 版本、结构化输出、成本计量、预算熔断
packages/shared 配置、日志脱敏、DB、Redis、错误码、中间件
packages/<业务域> identity / billing / task / agent / kb / retrieval / report …
services/ 需要独立伸缩的重型服务(换装、抠图、视觉),V1 为占位
prompts/ 按 <prompt_id>/<version>.txt 归档,与 ob_ai_call.prompt_version 对应
migrations/ Alembic;CI 强制 upgrade → downgrade → upgrade 往返可用

依赖方向由 lint-imports 强制(pyproject.toml 的 [tool.importlinter])。 apps → packages → domain 是单向的,业务包也不得绕过网关直连 provider。

提交前

make check      # lint + typecheck + imports + test + secrets,与 CI 同一套

单测不连库、不发网络请求。需要真实中间件的用例在 tests/integration, 默认跳过,用 make test-integration 显式开启。

两件容易踩的事

  • Prompt 固定前缀不许含时间戳、随机值等易变内容。 命中缓存的输入单价只有未命中的 约 1/30,前缀被污染会让输入成本翻数十倍。LLM_CACHE_PREFIX_MODE=strict 下启动即失败。
  • DeepSeek 自 2026-08-17 起峰谷定价,高峰(北京时间 09:00-12:00、14:00-18:00) 单价是空闲时段的 2 倍。单价配两套,由 packages/llm/cost.py 按调用时刻选择; 成本在调用当时算好落库,事后不按当前价重算。
S
Description
No description provided
Readme
1.4 MiB
Languages
Python 98.4%
Jinja 0.7%
Shell 0.5%
Makefile 0.3%