Files
beige/backend/app/workers/replenish_task.py
yangqianqian c5567614b4 修注释bug(score>=90→80红线)+核销表按代码真实状态纠偏
- pipeline_io.py/replenish_task.py 注释写90与代码实际80打架,统一为80(红线)
- 核销表纠正:文案先展示后台补=真做了/合格线80/M1本体已做
- M6标杆M7裂变改'草案先提炼再请北哥'(不干等),过滤策略条作废
2026-06-16 14:11:45 +08:00

101 lines
3.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
app/workers/replenish_task.py — 文案后台补充任务S1: 先展示后台补铁律)
合格文案(passed且score>=QUALITY_PASS_SCORE(80,红线)且非hard_block)不足用户目标条数时,
run_generation_pipeline 已先展示合格的; 此任务异步补齐到目标数或达上限。
只接收 task_id(基石B)。复用 pipeline_io.run_text_generation 的生成+过滤。
"""
import logging
from app.workers.celery_app import celery_app
logger = logging.getLogger(__name__)
# 补充上限:避免合格率低时无限补。最多补 MAX_REPLENISH_ROUNDS 轮。
MAX_REPLENISH_ROUNDS = 3
@celery_app.task(
bind=True,
name="app.workers.tasks.replenish_text_candidates",
max_retries=2,
default_retry_delay=30,
queue="generation",
)
def replenish_text_candidates(self, task_id: int) -> dict:
"""后台补充合格文案到目标条数(或达补充上限)。
每轮调用 run_text_generation 续生成,过滤后累加入库;
已合格数 >= text_count 即停; 达 MAX_REPLENISH_ROUNDS 仍不足也停(不卡用户)。
"""
from app.workers.tasks import _get_db, _push_event_sync
from app.workers.pipeline_io import run_text_generation
from app.workers.pipeline_steps import (
load_task_and_product,
decrypt_user_key,
build_clients_and_clear_key,
build_product_dict,
load_flywheel_context,
)
from app.models.task import TextCandidate
db = _get_db()
try:
task, product = load_task_and_product(db, task_id)
if not task:
logger.warning("补充任务找不到 task_id=%s", task_id)
return {"task_id": task_id, "replenished": 0, "reason": "task_not_found"}
# 已合格数(按入库的合格候选计)
existing = db.query(TextCandidate).filter(
TextCandidate.task_id == task_id
).count()
target = task.text_count
if existing >= target:
return {"task_id": task_id, "replenished": 0, "reason": "already_enough"}
workspace_id = task.workspace_id
plain_key = decrypt_user_key(db, task.operator_id, workspace_id)
clients = build_clients_and_clear_key(plain_key)
plain_key = None # 用完即清除基石B
product_dict = build_product_dict(product)
flywheel_fragment, _ = load_flywheel_context(
db, workspace_id, task.product_id, product_dict
)
seq = 9000 # 补充事件 seq 段,避开主流程
rounds = 0
# 真实入库合格数以 DB count 为准,绝不用 len(raw)(那是原始生成数含被过滤的低分条)。
# task47 实测踩坑len(raw)=2 但 saved=0(都没过90),误判达标提前停,库里仍缺。
current = existing
while current < target and rounds < MAX_REPLENISH_ROUNDS:
rounds += 1
run_text_generation(
db, clients, task, product_dict, flywheel_fragment,
_push_event_sync, workspace_id, seq,
)
# run_text_generation 内部已把本轮合格候选写库,这里重查真实库内条数
db.expire_all()
current = db.query(TextCandidate).filter(
TextCandidate.task_id == task_id
).count()
seq += 100
logger.info(
"补充轮 %d: task_id=%s 库内合格=%d/%d",
rounds, task_id, current, target,
)
return {
"task_id": task_id,
"replenished": current - existing,
"rounds": rounds,
"final": current,
"target": target,
}
except Exception as exc:
logger.error("replenish_text_candidates failed: task_id=%s err=%s", task_id, exc)
raise self.retry(exc=exc)
finally:
db.close()