#!/usr/bin/env python3 """Generate a reproducible blind random-combination corpus for deployed models. This corpus is evaluation-only. Its templates and slot vocabulary are kept separate from generate_corpus.py and must never be added to model training. """ from __future__ import annotations import argparse import json import random from dataclasses import asdict, dataclass from pathlib import Path DEFAULT_SEED = 20260826 DEFAULT_SAMPLES_PER_FAMILY = 20 @dataclass(frozen=True) class Labels: task: bool = False question: bool = False invitation: bool = False complaint: bool = False scheduleNegotiation: bool = False confirmationDecision: bool = False followUpReminder: bool = False sentiment: str = "neutral" replyable: bool = False @dataclass(frozen=True) class Record: id: str text: str language: str split: str family: str task: bool question: bool invitation: bool complaint: bool scheduleNegotiation: bool confirmationDecision: bool followUpReminder: bool sentiment: str replyable: bool SLOTS = { "zh-Hans": { "discourse": ["", "对了,", "另外,", "补充一下,", "还有一件事,", "先说重点,", "顺便提一句,", "刚想到,", "简单说,", "单独记一下,"], "owner": ["设计同学", "财务", "供应商", "项目负责人", "客服团队", "运营"], "artifact": ["验收截图", "预算备注", "测试结论", "签字页", "交付清单", "复盘摘要"], "deadline": ["午休前", "明晚之前", "本周收尾时", "下次评审前", "两个工作日内", "月底前"], "channel": ["群里", "工单下方", "邮件线程里", "共享文档中", "项目卡片上"], "topic": ["费用调整", "权限开通", "排期变动", "售后范围", "资料归档", "版本上线"], "event": ["参加小范围评审", "吃顿便饭", "看内部演示", "碰面聊方案", "参加庆功会"], "time": ["周六傍晚", "明天十点半", "下周三午后", "今晚九点", "周一早会后"], "alternate": ["周二四点半", "周四午休后", "明早第一段时间", "周五临下班前", "下周一下午"], "place": ["楼下咖啡店", "三号会议室", "园区北门", "线上会议室", "客户办公室"], "issue": ["页面一直空白", "付款结果重复扣款", "附件始终打不开", "物流状态停了五天", "账号又被锁住"], "impact": ["工作完全卡住", "客户已经在催", "我无法继续操作", "交付时间被耽误", "家人收不到商品"], "option": ["轻量版本", "第二套报价", "供应商丙", "季度结算", "先灰度发布", "线下处理方案"], "trigger": ["客户回信", "补丁上线", "款项入账", "复诊结束", "合同盖章", "样品送达"], "person": ["客户经理", "医生", "仓库负责人", "法务", "房东", "招聘方"], "thing": ["最终结论", "下一步安排", "到账情况", "补充材料", "交付日期", "处理进度"], "update": ["我刚到酒店", "演示比预想顺利", "路上有点堵", "今天终于忙完了", "刚看到你发的照片"], "positive": ["这次响应非常快", "新流程顺手多了", "处理结果超出预期", "讲解特别清楚", "修复后体验很好"], "negative_news": ["行业指数连续回落", "昨夜航班大面积延误", "原材料价格再次上涨", "部分门店暂停营业", "天气预警已经升级"], "fact": ["仓库共有三层", "合同附件为 PDF", "当前版本号是 2.1", "展厅周一闭馆", "蓝色标签表示已归档"], }, "en": { "discourse": ["", "Also, ", "One more thing: ", "For context, ", "The main point is this: ", "Just to add, ", "By the way, ", "A quick note: ", "In short, ", "For the record, "], "owner": ["Design", "Finance", "the vendor", "the project lead", "Support", "Operations"], "artifact": ["acceptance screenshots", "budget notes", "test findings", "signature page", "delivery checklist", "retro summary"], "deadline": ["before lunch", "by tomorrow evening", "as this week closes", "before the next review", "within two business days", "before month-end"], "channel": ["in the group thread", "under the ticket", "in the email chain", "inside the shared document", "on the project card"], "topic": ["the fee adjustment", "access activation", "the timeline change", "support coverage", "document archiving", "the release"], "event": ["join a small review", "have a casual dinner", "watch the internal demo", "meet to discuss the proposal", "attend the celebration"], "time": ["Saturday evening", "tomorrow at 10:30", "next Wednesday afternoon", "tonight at nine", "after Monday's stand-up"], "alternate": ["Tuesday at 4:30", "after lunch on Thursday", "first thing tomorrow", "late Friday afternoon", "next Monday afternoon"], "place": ["the cafe downstairs", "meeting room three", "the north campus gate", "the online room", "the client office"], "issue": ["the page stays blank", "the payment was charged twice", "the attachment never opens", "tracking has not moved for five days", "the account is locked again"], "impact": ["all work is blocked", "the client is already chasing us", "I cannot continue", "delivery is now delayed", "my family cannot receive the item"], "option": ["the lightweight version", "the second quote", "vendor C", "quarterly billing", "a limited rollout first", "the offline resolution"], "trigger": ["the client replies", "the patch ships", "the payment lands", "the checkup ends", "the contract is signed", "the sample arrives"], "person": ["the account manager", "the doctor", "the warehouse lead", "Legal", "the landlord", "the recruiter"], "thing": ["the final decision", "next steps", "payment status", "the missing documents", "the delivery date", "resolution progress"], "update": ["I just reached the hotel", "the demo went better than expected", "traffic is a little slow", "I finally wrapped up today", "I just saw the photo you sent"], "positive": ["the response was exceptionally fast", "the new flow is much easier", "the outcome exceeded expectations", "the explanation was crystal clear", "the fix feels solid"], "negative_news": ["the industry index fell again", "many flights were delayed overnight", "raw material prices rose again", "several stores paused operations", "the weather alert was upgraded"], "fact": ["the warehouse has three floors", "the contract attachment is a PDF", "the current version is 2.1", "the showroom closes on Mondays", "a blue label means archived"], }, } def labels(**values: object) -> Labels: return Labels(**values) FAMILIES = { "task_request": { "labels": labels(task=True, replyable=True), "templates": { "zh-Hans": [ "{owner}还缺{artifact},麻烦{deadline}补齐后在{channel}留言。", ], "en": [ "{owner} still needs the {artifact}; please add it {deadline} and leave a note {channel}.", ], }, }, "task_next_action": { "labels": labels( task=True, followUpReminder=True, replyable=True, ), "templates": { "zh-Hans": [ "下一步由你整理{artifact},请在{deadline}交给{owner}。", ], "en": [ "Your next action is to prepare the {artifact} {deadline} for {owner}.", ], }, }, "information_question": { "labels": labels(question=True, replyable=True), "templates": { "zh-Hans": ["想核实一下,{topic}现在由谁拍板?", "{topic}目前走到哪一步了,方便说明吗?"], "en": ["Quick check: who owns the final call on {topic}?", "Where does {topic} stand right now?"], }, }, "fixed_invitation": { "labels": labels(question=True, invitation=True, replyable=True), "templates": { "zh-Hans": ["我给你留了位置,{time}到{place}{event},能来不?", "{time}我们在{place}{event},要不要一起?"], "en": ["I saved you a spot to {event} {time} at {place}; can you make it?", "Want to {event} with us {time} at {place}?"], }, }, "complaint_support": { "labels": labels(question=True, complaint=True, sentiment="negative", replyable=True), "templates": { "zh-Hans": ["我已经重试三次,还是{issue},导致{impact}。请问什么时候能处理?", "{issue}到现在没解决,{impact},能给一个明确答复吗?"], "en": ["I have tried three times and {issue}; {impact}. When will this be fixed?", "{issue} is still unresolved and {impact}. Can I get a clear answer?"], }, }, "schedule_negotiation": { "labels": labels(question=True, scheduleNegotiation=True, replyable=True), "templates": { "zh-Hans": ["原来的时段卡住了,我只能{alternate},能不能对调?", "{time}赶不过去,换成{alternate}你觉得可行吗?"], "en": ["The original slot is blocked for me; could we swap to {alternate}?", "I cannot make {time}. Would {alternate} be workable instead?"], }, }, "confirmation_decision": { "labels": labels(confirmationDecision=True, replyable=True), "templates": { "zh-Hans": ["不用再比较了,就选{option},后续都按这个口径走。", "我正式确认{option},请{deadline}启动后续安排。"], "en": ["No more comparisons: choose {option} and use it as the final direction.", "I formally approve {option}; start the next steps {deadline}."], }, }, "follow_up_instruction": { "labels": labels( task=True, followUpReminder=True, replyable=True, ), "templates": { "zh-Hans": ["等{trigger}后第二天再找{person}确认{thing},别漏了。"], "en": ["Once {trigger}, check with {person} the next day about {thing}."], }, }, "follow_up_personal_reminder": { "labels": labels(followUpReminder=True, replyable=False), "templates": { "zh-Hans": ["个人备忘:提醒我{deadline}联系{person},追一下{thing}。"], "en": ["Note to self: remind me to contact {person} {deadline} about {thing}."], }, }, "conversation": { "labels": labels(replyable=True), "templates": { "zh-Hans": ["跟你说一声,{update},晚点再聊。", "{update},突然想到你可能会想知道。"], "en": ["Just letting you know, {update}; we can talk later.", "{update}, and I thought you might want to know."], }, }, "acknowledgment_boundary": { "labels": labels(), "templates": { "zh-Hans": ["看到了,先这样,不需要回复。", "嗯,内容已收到,我只是确认一下。"], "en": ["Seen, that is all for now; no reply needed.", "Okay, I received it. This is only an acknowledgment."], }, }, "quoted_question_boundary": { "labels": labels(), "templates": { "zh-Hans": ["文档标题是“{topic}怎么办?”,这里不是在问你。", "纪要保留了“谁负责{topic}?”这句话,答案已经写在后面。"], "en": ["The document heading says “What about {topic}?”, but it is not asking you.", "The notes preserve the question “Who owns {topic}?”, which is answered below."], }, }, "event_boundary": { "labels": labels(), "templates": { "zh-Hans": ["公告只记录一件事:{event}定在{time},地点是{place}。", "历史行程显示他们曾在{place}{event},没有邀请任何人。"], "en": ["The notice only records that they will {event} {time} at {place}.", "The old itinerary says they went to {place} to {event}; nobody is being invited."], }, }, "vague_future_boundary": { "labels": labels(), "templates": { "zh-Hans": ["哪天有心情再找{person}聊{thing}吧。", "以后也许会看看{topic},目前没有安排。"], "en": ["Maybe I will talk to {person} about {thing} someday.", "I may revisit {topic} eventually, but there is no plan."], }, }, "positive_feedback": { "labels": labels(sentiment="positive", replyable=True), "templates": { "zh-Hans": ["必须夸一下,{positive},谢谢你们。", "{positive},整个过程让人很安心。"], "en": ["Credit where it is due: {positive}. Thank you.", "{positive}, and the whole process felt reassuring."], }, }, "negative_news": { "labels": labels(sentiment="negative"), "templates": { "zh-Hans": ["新闻简报显示,{negative_news},本文仅陈述情况。", "数据显示{negative_news},没有提出处理诉求。"], "en": ["The news brief reports that {negative_news}; this is only a factual summary.", "Data shows that {negative_news}, with no request for support."], }, }, "neutral_fact": { "labels": labels(), "templates": { "zh-Hans": ["资料页写明:{fact}。", "当前记录只包含一个事实:{fact}。"], "en": ["The reference page states that {fact}.", "The current record contains one fact: {fact}."], }, }, } FRESH_FAMILIES = { "fresh_task_assignment": { "labels": labels(task=True, replyable=True), "templates": { "zh-Hans": [ "这份交付由你收尾:把{artifact}整理好,最迟{deadline}交给{owner}。", "{owner}把{artifact}分给你处理,完成时间不能晚于{deadline}。", ], "en": [ "You are closing out this deliverable: finish the {artifact} and give it to {owner} {deadline}.", "{owner} assigned the {artifact} to you, with completion required {deadline}.", ], }, }, "fresh_task_question": { "labels": labels(task=True, question=True, replyable=True), "templates": { "zh-Hans": [ "{artifact}能由你在{deadline}前收尾吗?完成后告诉{owner}。", "这项分工你能接吗:{deadline}整理{artifact}?", ], "en": [ "Can you close out the {artifact} {deadline} and update {owner}?", "Can you take this assignment and finish the {artifact} {deadline}?", ], }, }, "fresh_self_plan_boundary": { "labels": labels(), "templates": { "zh-Hans": [ "我可能自己看看{topic},但还没决定什么时候做。", "只是个人想法:以后也许整理{artifact},目前没有安排。", ], "en": [ "I may look into {topic} myself, but I have not decided when.", "This is only a personal idea: perhaps I will organize the {artifact} someday.", ], }, }, "fresh_complaint": { "labels": labels(complaint=True, sentiment="negative", replyable=True), "templates": { "zh-Hans": [ "本来承诺今天解决,结果还是{issue},现在{impact}。", "同样的故障第三次出现,{issue},整个事情已经{impact}。", ], "en": [ "This was promised for today, yet {issue}, and now {impact}.", "The same failure has happened a third time: {issue}, so {impact}.", ], }, }, "fresh_complaint_request": { "labels": labels( question=True, complaint=True, sentiment="negative", replyable=True, ), "templates": { "zh-Hans": [ "{issue}已经影响到{impact},你们准备哪天真正解决?", "因为{issue},现在{impact},能不能给出明确处理时限?", ], "en": [ "{issue} has reached the point where {impact}. When will you actually resolve it?", "Because {issue}, {impact}. Can you provide a firm resolution date?", ], }, }, "fresh_negative_report_boundary": { "labels": labels(sentiment="negative"), "templates": { "zh-Hans": [ "行业通报称{negative_news},这里只摘录公开信息。", "统计报告记录了{negative_news},没有客户投诉。", ], "en": [ "The industry bulletin says that {negative_news}; this only quotes public information.", "The statistical report records that {negative_news}, with no customer complaint.", ], }, }, "fresh_confirmation": { "labels": labels(confirmationDecision=True, replyable=True), "templates": { "zh-Hans": [ "评审结束,我的最终选择是{option},其他方案关闭。", "结论正式生效:{topic}采用{option}。", ], "en": [ "The review is over; my final selection is {option}, and the alternatives are closed.", "The decision is now official: use {option} for {topic}.", ], }, }, "fresh_pending_boundary": { "labels": labels(), "templates": { "zh-Hans": [ "我看过{option}了,但还没有选择,等明天再决定。", "{topic}仍在评审,当前没有批准结论。", ], "en": [ "I reviewed {option}, but have not selected it; the decision waits until tomorrow.", "{topic} remains under review, with no approval yet.", ], }, }, "fresh_follow_up": { "labels": labels( task=True, followUpReminder=True, replyable=True, ), "templates": { "zh-Hans": [ "等{trigger}满两天后,再找{person}核实{thing}并记录结果。", "当前事项结束以后,回头联系{person}追踪{thing}。", ], "en": [ "Two days after {trigger}, check with {person} again about {thing} and record the outcome.", "After the current item closes, return to {person} and track {thing}.", ], }, }, "fresh_personal_reminder": { "labels": labels(followUpReminder=True), "templates": { "zh-Hans": [ "给自己设一条后续提醒:{deadline}找{person}确认{thing}。", "个人行动项:{trigger}以后再次检查{thing}。", ], "en": [ "Set myself a follow-up reminder to ask {person} about {thing} {deadline}.", "Personal action item: check {thing} again after {trigger}.", ], }, }, "fresh_plain_task_boundary": { "labels": labels(task=True, replyable=True), "templates": { "zh-Hans": [ "现在请直接整理{artifact}并发给{owner},不需要后续回访。", "一次性完成{artifact}即可,交给{owner}后任务结束。", ], "en": [ "Prepare the {artifact} now and send it to {owner}; no later follow-up is needed.", "Complete the {artifact} once, deliver it to {owner}, and close the task.", ], }, }, "fresh_vague_follow_boundary": { "labels": labels(), "templates": { "zh-Hans": [ "以后说不定会再问{person},目前没有后续计划。", "{thing}哪天想起来再看,现在不用提醒。", ], "en": [ "I might ask {person} again someday, but there is no follow-up plan.", "Maybe I will revisit {thing} whenever it comes to mind; no reminder is needed.", ], }, }, } TARGETED_FINAL_FAMILIES = { "final_task_direct": { "labels": labels(task=True, replyable=True), "templates": { "zh-Hans": [ "{artifact}现在明确由你负责,{deadline}前交给{owner}。", "请你承担{artifact}的交付,完成后在{channel}确认。", ], "en": [ "Ownership of the {artifact} now belongs to you; deliver it to {owner} {deadline}.", "You are responsible for delivering the {artifact}; confirm completion {channel}.", ], }, }, "final_task_indirect": { "labels": labels(task=True, replyable=True), "templates": { "zh-Hans": [ "{owner}希望你能接下{artifact},并在{deadline}前收尾。", "这件事想交给你继续推进:整理{artifact}。", ], "en": [ "{owner} is counting on you to pick up the {artifact} and close it out {deadline}.", "We would like you to carry this forward by preparing the {artifact}.", ], }, }, "final_task_question": { "labels": labels(task=True, question=True, replyable=True), "templates": { "zh-Hans": [ "能请你负责{artifact}并在{deadline}前完成吗?", "{artifact}接下来可以由你收尾吗?", ], "en": [ "Would you be able to own the {artifact} and finish it {deadline}?", "Could the {artifact} be left with you for final completion?", ], }, }, "final_personal_action_boundary": { "labels": labels(followUpReminder=True), "templates": { "zh-Hans": [ "这是我自己的行动清单:{trigger}后检查{thing}。", "个人记录,不是委派:{deadline}找{person}确认{thing}。", ], "en": [ "This is on my own action list: check {thing} after {trigger}.", "Personal note, not delegated work: ask {person} about {thing} {deadline}.", ], }, }, "final_self_intent_boundary": { "labels": labels(), "templates": { "zh-Hans": [ "我自己可能会整理{artifact},但还没有正式计划。", "以后有空我再看{topic},目前不用安排。", ], "en": [ "I may organize the {artifact} myself, but there is no firm plan.", "I might look at {topic} when I have time; nothing is scheduled.", ], }, }, "final_event_boundary": { "labels": labels(), "templates": { "zh-Hans": [ "{owner}在{deadline}举行评审,这只是日程通知。", "{topic}会议已经定在{deadline},没有分配任务。", ], "en": [ "{owner} is holding a review {deadline}; this is only a calendar notice.", "The meeting about {topic} is set for {deadline}, with no assignment.", ], }, }, "final_complaint_implicit": { "labels": labels(complaint=True, sentiment="negative", replyable=True), "templates": { "zh-Hans": [ "我不应该为同一个问题反复追问,{issue},现在{impact}。", "又是同样的结果:{issue},已经连续影响到{impact}。", ], "en": [ "I should not have to chase the same issue repeatedly: {issue}, and now {impact}.", "It is the same outcome again: {issue}, repeatedly leaving me with {impact}.", ], }, }, "final_complaint_short": { "labels": labels(complaint=True, sentiment="negative", replyable=True), "templates": { "zh-Hans": [ "{issue},已经第三次了。", "等了这么久还是{issue},实在无法接受。", ], "en": [ "{issue}. This is already the third time.", "After all this waiting, {issue}; this is not acceptable.", ], }, }, "final_complaint_request": { "labels": labels( question=True, complaint=True, sentiment="negative", replyable=True, ), "templates": { "zh-Hans": [ "{issue}一直没有变化,什么时候才能真正处理?", "因为{issue},现在{impact},谁能给出解决结果?", ], "en": [ "Nothing has changed with this problem: {issue}. When will it actually be handled?", "Because {issue}, {impact}. Who can provide a real resolution?", ], }, }, "final_negative_fact_boundary": { "labels": labels(sentiment="negative"), "templates": { "zh-Hans": [ "公开报告显示{negative_news},这里没有服务申诉。", "资料仅记录{negative_news},不涉及个人问题。", ], "en": [ "The public report shows that {negative_news}; there is no service grievance here.", "The document only records that {negative_news}, not an individual problem.", ], }, }, "final_resolved_boundary": { "labels": labels(), "templates": { "zh-Hans": [ "之前的{issue}已经彻底恢复,这是一条结案记录。", "{topic}的问题处理完毕,现在不需要任何支持。", ], "en": [ "The earlier issue where {issue} is fully resolved; this is a closure record.", "The problem involving {topic} is complete, with no support needed now.", ], }, }, "final_operational_task_boundary": { "labels": labels(task=True, replyable=True), "templates": { "zh-Hans": [ "请完成{artifact}后直接结项,不需要投诉或后续回访。", "{deadline}前把{artifact}交给{owner},随后流程关闭。", ], "en": [ "Complete the {artifact} and close the item; no complaint or later follow-up is involved.", "Deliver the {artifact} to {owner} {deadline}, then close the workflow.", ], }, }, } TARGETED_CONFIRMATION_FAMILIES = { "confirmation_task_assignment": { "labels": labels(task=True, replyable=True), "templates": { "zh-Hans": [ "请你把{artifact}负责到底,并在{deadline}向{owner}交付。", "{artifact}接下来归你处理,完成后在{channel}更新状态。", ], "en": [ "Please see the {artifact} through and deliver it to {owner} {deadline}.", "The {artifact} is yours to handle next; update the status {channel} when complete.", ], }, }, "confirmation_task_request": { "labels": labels(task=True, question=True, replyable=True), "templates": { "zh-Hans": [ "可以请你接管{artifact}并在{deadline}前处理好吗?", "你愿意负责{artifact}的最后交付吗?", ], "en": [ "Could I ask you to take care of the {artifact} {deadline}?", "Would you own the final delivery of the {artifact}?", ], }, }, "confirmation_operational_task": { "labels": labels(task=True, replyable=True), "templates": { "zh-Hans": [ "把{artifact}交给{owner}后直接关闭事项,不安排回访。", "当前只需要完成{artifact},没有投诉处理。", ], "en": [ "Close the item after sending the {artifact} to {owner}; do not schedule a follow-up.", "The only requirement is to complete the {artifact}; no grievance handling is involved.", ], }, }, "confirmation_personal_boundary": { "labels": labels(followUpReminder=True), "templates": { "zh-Hans": [ "我自己的行动备忘:{trigger}后查看{thing}。", "仅记录个人计划,{deadline}联系{person}。", ], "en": [ "My private action note is to review {thing} after {trigger}.", "This only records my personal plan to contact {person} {deadline}.", ], }, }, "confirmation_self_plan_boundary": { "labels": labels(), "templates": { "zh-Hans": [ "我也许会自己整理{artifact},目前没有确定安排。", "{topic}以后再考虑,现在谁都不用处理。", ], "en": [ "I may prepare the {artifact} myself, but nothing is arranged.", "{topic} can be considered later; nobody needs to handle it now.", ], }, }, "confirmation_complaint_implicit": { "labels": labels(complaint=True, sentiment="negative", replyable=True), "templates": { "zh-Hans": [ "我到现在还在面对{issue},而且{impact}。", "处理承诺没有兑现,结果仍然是{issue}。", ], "en": [ "I am still dealing with the fact that {issue}, and {impact}.", "The promised fix never materialized; the result is still that {issue}.", ], }, }, "confirmation_complaint_request": { "labels": labels( question=True, complaint=True, sentiment="negative", replyable=True, ), "templates": { "zh-Hans": [ "{issue}已经持续很久,究竟什么时候恢复?", "现在因为{issue}而{impact},谁来负责处理?", ], "en": [ "This has continued for far too long: {issue}. When will it be restored?", "Because {issue}, {impact}. Who is responsible for fixing it?", ], }, }, "confirmation_complaint_short": { "labels": labels(complaint=True, sentiment="negative", replyable=True), "templates": { "zh-Hans": [ "还是{issue},完全没有改善。", "{issue}又来了,不能一直这样。", ], "en": [ "It is still the case that {issue}, with no improvement.", "The problem is back again: {issue}. This cannot keep happening.", ], }, }, "confirmation_negative_fact": { "labels": labels(sentiment="negative"), "templates": { "zh-Hans": [ "研究资料指出{negative_news},这不是客户反馈。", "行业统计记录了{negative_news},没有服务诉求。", ], "en": [ "The research notes that {negative_news}; this is not customer feedback.", "Industry statistics record that {negative_news}, with no service request.", ], }, }, "confirmation_resolved_boundary": { "labels": labels(), "templates": { "zh-Hans": [ "{issue}已经恢复,{owner}确认事项关闭。", "{topic}当前运行正常,不需要补救。", ], "en": [ "The earlier state where {issue} is resolved, and {owner} confirmed closure.", "{topic} is operating normally now, with no remedy needed.", ], }, }, } TARGETED_RELEASE_FAMILIES = { "release_task_owner": { "labels": labels(task=True, replyable=True), "templates": { "zh-Hans": [ "{artifact}的负责人就是你,请在{deadline}完成交付。", "接下来请你推进{artifact},并向{owner}汇报结果。", ], "en": [ "You are the owner of the {artifact}; complete delivery {deadline}.", "Please move the {artifact} forward and report the outcome to {owner}.", ], }, }, "release_task_polite_request": { "labels": labels(task=True, question=True, replyable=True), "templates": { "zh-Hans": [ "能麻烦你把{artifact}负责到交付完成吗?", "你可以在{deadline}前处理好{artifact}吗?", ], "en": [ "May I ask you to own the {artifact} through delivery?", "Can you have the {artifact} completed {deadline}?", ], }, }, "release_personal_boundary": { "labels": labels(followUpReminder=True), "templates": { "zh-Hans": [ "这是我的私人待办:{trigger}之后确认{thing}。", "个人备忘,不交给任何人:{deadline}联系{person}。", ], "en": [ "This is my private todo: confirm {thing} after {trigger}.", "Personal reminder, assigned to nobody else: contact {person} {deadline}.", ], }, }, "release_complaint_unspoken": { "labels": labels(complaint=True, sentiment="negative", replyable=True), "templates": { "zh-Hans": [ "从上次反馈以后仍然{issue},现在已经{impact}。", "说好的处理没有发生,我看到的还是{issue}。", ], "en": [ "Since my last report, {issue}, and it has now reached the point where {impact}.", "The promised handling did not happen; I am still seeing that {issue}.", ], }, }, "release_complaint_question": { "labels": labels( question=True, complaint=True, sentiment="negative", replyable=True, ), "templates": { "zh-Hans": [ "{issue}到现在都没处理,什么时候能恢复正常?", "目前因为{issue}而{impact},可以给个处理结果吗?", ], "en": [ "The problem where {issue} has not been addressed. When will normal service return?", "At the moment, {issue}, so {impact}. Can I get an actual resolution?", ], }, }, "release_complaint_brief": { "labels": labels(complaint=True, sentiment="negative", replyable=True), "templates": { "zh-Hans": [ "{issue},到现在还是老样子。", "又一次{issue},这已经影响正常使用。", ], "en": [ "{issue}, and nothing has changed.", "Once again, {issue}; normal use is now affected.", ], }, }, "release_negative_boundary": { "labels": labels(sentiment="negative"), "templates": { "zh-Hans": [ "分析报告提到{negative_news},不代表用户投诉。", "公开数据包含{negative_news},这里只做事实引用。", ], "en": [ "The analysis mentions that {negative_news}; it does not represent a user complaint.", "Public data includes the fact that {negative_news}; this is only a factual citation.", ], }, }, "release_resolved_boundary": { "labels": labels(), "templates": { "zh-Hans": [ "{issue}的问题已经结束,目前状态稳定。", "{topic}已确认恢复,{owner}不需要继续介入。", ], "en": [ "The earlier problem where {issue} is over, and the current state is stable.", "{topic} is confirmed restored, so {owner} does not need to intervene.", ], }, }, } def render(template: str, slots: dict[str, list[str]], rng: random.Random) -> str: values = {key: rng.choice(options) for key, options in slots.items()} return values["discourse"] + template.format(**values) def generate( seed: int, samples_per_family: int, families: dict[str, dict[str, object]], ) -> list[Record]: rng = random.Random(seed) records: list[Record] = [] seen: set[str] = set() for language in ("zh-Hans", "en"): slots = SLOTS[language] for family, configuration in families.items(): family_labels: Labels = configuration["labels"] templates: list[str] = configuration["templates"][language] generated = 0 attempts = 0 while generated < samples_per_family: attempts += 1 if attempts > samples_per_family * 200: raise RuntimeError(f"Unable to generate unique samples for {language}/{family}") text = render(rng.choice(templates), slots, rng) normalized = " ".join(text.casefold().split()) if normalized in seen: continue seen.add(normalized) record_id = f"random-{seed}-{language}-{family}-{generated + 1:03d}" records.append( Record( id=record_id, text=text, language=language, split="randomHoldout", family=family, **asdict(family_labels), ) ) generated += 1 rng.shuffle(records) return records def main() -> None: parser = argparse.ArgumentParser() parser.add_argument("--seed", type=int, default=DEFAULT_SEED) parser.add_argument("--samples-per-family", type=int, default=DEFAULT_SAMPLES_PER_FAMILY) parser.add_argument( "--profile", choices=( "development", "fresh", "targeted-final", "targeted-confirmation", "targeted-release", ), default="development", ) parser.add_argument( "--output", type=Path, default=None, ) arguments = parser.parse_args() profiles = { "development": FAMILIES, "fresh": FRESH_FAMILIES, "targeted-final": TARGETED_FINAL_FAMILIES, "targeted-confirmation": TARGETED_CONFIRMATION_FAMILIES, "targeted-release": TARGETED_RELEASE_FAMILIES, } families = profiles[arguments.profile] default_outputs = { "development": "random-holdout-corpus.jsonl", "fresh": "fresh-metric-holdout-corpus.jsonl", "targeted-final": "targeted-final-holdout-corpus.jsonl", "targeted-confirmation": "targeted-confirmation-holdout-corpus.jsonl", "targeted-release": "targeted-release-holdout-corpus.jsonl", } output_path = arguments.output or Path( "ModelTraining/ClipboardSemantics/" + default_outputs[arguments.profile] ) records = generate(arguments.seed, arguments.samples_per_family, families) output_path.parent.mkdir(parents=True, exist_ok=True) with output_path.open("w", encoding="utf-8") as output: for record in records: output.write(json.dumps(asdict(record), ensure_ascii=False, sort_keys=True) + "\n") print( f"RANDOM_HOLDOUT_DONE records={len(records)} " f"families={len(families)} profile={arguments.profile} " f"seed={arguments.seed} output={output_path}" ) if __name__ == "__main__": main()