智能挑票
把用户的中文业务要求和本地票据池转换为可复核的挑票清单、计算结果及审计信息。模型负责理解业务语言和表头,引擎负责确定性筛选、金额组合、分类、计息、舍入与合计。
运行环境:需要 Python 3.10+;读取 XLS 需要 xlrd,读取或导出 XLSX 需要 openpyxl。宿主 Agent 必须能够读取本地文件并执行 Python。
本次业务边界
- 新业务从空 job 重新构造,不默认继承上一单的利率、交易日、金额、期限、筛选/排序或计息开关;历史聊天、长期记忆和模板示例不是本轮指令。
- 同一业务的澄清、追加筛选和调整可以延续:保持任务标识,只保留仍有效的本任务确认,修改/撤销字段同步替换/删除。明确“沿用上次利率”时只继承点名字段;不明确且会影响结果时澄清,不能机械地逐消息清空,也不能整单照搬。
- 每次构造 job 时读取任务隔离与参数来源,记录
task_context;正常执行必须带--require-task-context。缺少本轮必要要素时澄清,纯挑票保持calculate=false。记录校验失败不得改走兼容入口或底层引擎绕过。环境缓存可复用,不等于业务要素可复用。
默认决策口径
- 用户明确提出的筛选条件、排除条件和目标金额优先于排序偏好。
- 普通挑票语境中的“金额”默认指票面金额,源表裸列名“金额”也默认映射为票面金额;回购任务中“做 3 亿回购”的 3 亿仍指待选票据票面总额,不能改成回购融资金额。质押式回购需要计息但用户没有另行说明回购融资本金时,
repo_amount自动取最终入选票据的实际票面总额,不向用户追问;用户明确给出回购金额时才覆盖该默认值。目标金额与实际入选额有偏差时,默认本金跟随实际入选额,而不是照抄目标金额。 - 用户只说“挑 3 亿”而未给容差时,默认在符合条件的票中尽量接近 3 亿,允许略高或略低;金额偏差优先,用户指定的期限、利率、价差等排序用于次级取舍。
- 符合条件的票面总额不足目标时,选择全部符合条件的票,并明确说明缺口;没有符合条件的票时如实说明。
- LLM 根据语义决定字段。例如“非江苏银行承兑”映射到
acceptor_exclude_keywords,“不要某直贴行”映射到discount_bank_exclude_keywords;“非国股承兑”映射到acceptor_market_groups_exclude,“非二类贴现行”映射到discount_tier_classes_exclude。不要在引擎外手工删行或手工维护反向机构名单。 - 直贴行/贴现行指对该张票办理直贴的银行,源表“直贴行名称”“直贴行”“贴现行名称”“贴现行”优先映射到
discount_bank_name。“机构名称”可能只是业务发生机构或所属机构,不能与明确直贴行列竞争;仅在源表没有任何明确直贴行/贴现行列时,作为旧版直贴业务导出表的兼容兜底。两类列同时存在时必须自动使用明确直贴行列,不向用户询问二选一。 - 承兑/付款主体优先映射到
acceptor_name:承兑行、承兑人、付款人、承兑银行、付款银行、承兑企业、付款企业、付款行及其名称列。“承兑人开户行”等仅映射到acceptor_bank_name,保留为最后兜底:只有票种已独立确认为银票、无未决票种冲突且明确主体缺失时才可使用。商票、财票及票种未决记录禁止用开户行代替付款人;不能先用开户行推断银票再开启兜底。主体存在但无法分类或表头有歧义,不等于主体缺失。承兑端分类及正负关键词统一使用最终主体,开户行兜底须披露。 - 机构类别简称按所在端理解:“城贴”“农贴”“大商贴”分别映射到
discount_market_groups的普通城商、农商、大商;“城商承兑”“农商承兑”映射到acceptor_market_groups。允许把“城”“农”等柜台简称交给引擎别名解析,不要求用户说完整分类名。“城农票”固定理解为银票,且承兑端仅限普通城商与农商行/农村合作金融机构,不含大商和村镇银行;对应bill_types=["银票"]、acceptor_market_groups=["城农票"]。 - 未明确指定贴现端时,“国股票”“大商票”优先指国股银行承兑、大商承兑的银票,分别映射到
bill_types=["银票"]加acceptor_market_groups=["国股"]/["大商"];不默认映射为“国股贴/国贴”或“大商贴”,也不把“国股票”限成“双国”。明确的“贴/直贴/贴现行”仍映射贴现端,否定说法使用相应承兑端_exclude。 - “足月”按本项目确认的票据业务口径:
12×(实际到期年-系统当前年)+实际到期月-系统当前月 = 6,只比较年月、不比较日号,不等同于180/184天或不少于6个月。读取运行时系统日期,将系统当前月后第6个月的月初/月末映射为due_date_from/due_date_to;使用顺延后的实际到期月份,不以用户交易日替代系统月份基准。 - 无特殊说明时,“跨年票”指实际到期日晚于系统当前年 12 月 31 日的票。读取运行时系统年 Y,映射
due_date_from=(Y+1)-01-01,不默认添加下一年年底的上限;它不是“仅下一年到期”的同义词。名义到期在年内但顺延后实际到期跨年的也属于跨年票。默认基准不因另有交易日而改变;用户明确另定基准或额外日期范围时才按其要求处理。跨年仅是筛选条件,不提供交易日、不推断利率、不自动计息,见跨年模板。 O/N、ON、隔夜、1D、7D、14D、1M—6M等期限代码必须先按业务类型解释,详见期限代码映射。贴现、转贴现及普通挑票中表示票据剩余期限:O/N/1D精确1天,7D/14D默认±1天,月期限按日历月目标日默认±3天;回购类业务中表示精确回购期限,日期限写入repo_days,月期限由首期结算日推算repo_maturity_date和实际repo_days。用户给定容差覆盖默认值;月期限不得固定按30天换算。“足月”不是6M别名,继续使用上一条整月口径。- 每次挑票都在
intent.filters.due_dates_exclude中写入运行时系统当天,以及用户明确指定的本次交易日(若有,去重);直贴、转贴、回购及calculate=false一律适用。另将用户明确的本次交易日/结算日写入parameters.trade_date/parameters.interest_start_date:引擎自动剔除实际到期日不晚于该日期的票,无需询问是否纳入此前到期票据。不能用名义到期日、票据历史交易日或源剩余天数代替本次业务日期;缺少可确认的实际到期日才澄清。日期范围、金额组合与排序在这些排除条件下执行;详见日期映射模板。 - 源表提供明确的一至五类承兑行分类时,优先用于
tier_class分级筛选;没有或无法识别时才用技能策略兜底。源表一至五类内部评级不能直接当成“国股/城商”等market_group:市场分组仍须根据承兑人/贴现行名称和版本化策略判断并披露策略版本。源表分级与策略推断不一致时继续采用源表分级并告警,不能静默覆盖市场分组。 - 用户只说“中信”时默认指中信银行;明确说“中信银行国际(中国)”“CNCBI”等才指外资法人。用户只说“国民”时默认按民生银行理解;明确说“国民银行(中国)”“KB”等才指外资法人。
- “供票”映射到
is_supply_chain_bill=true,“非供票”映射到false;供票身份必须来自有效30位票号,不能按承兑人或出票人名称猜测。 - 用户没有给排序偏好时保留源顺序。不得为了跑通而把
inventory_rate冒充trade_rate,或把一个日期字段冒充另一个日期字段。 - 默认不计算利息。只有用户明确要求计算,明确给出本次交易利率,或语义上要求收益、价差、成本、利息收入/支出、利息、实付等计算结果时,才设置
calculate=true;用户明确“只挑票/不计息”优先,不因历史利率、源表带利率列或仅按利率筛选就开启计算。不要只靠机械关键词命中。 - 需要计算但未说明业务类型时,默认按贴现/转贴现处理。用户只说回购、质押、买返时默认质押式回购;明确买断式回购才启用买断式回购。再贴现按本技能约定映射为质押式回购,并在结果中明确披露。
- 在库利率、交易利率、持票成本是三个独立字段。本次统一参数优先于逐票值,并统一用于筛选、排序与计算,源值另行保留。交易价差使用“在库利率-交易利率”;持有息差使用“在库利率-持票成本”。真正未提供持票成本时按 0 处理并披露;提供了但解析失败、单位或映射不明时,只要排序或计算依赖它就先澄清,不能默认成 0。裸“利率、价格、买入利率、买入价格、贴入利率、贴入价格、首期利率”不能在关键计算中自动二选一。
- 利率的业务含义和存储单位是两件事。Excel 百分比格式按底层小数读取;带
%/‰或表头带单位的值按明确单位读取;无格式、无后缀的裸利率不能按数值大小猜单位,需要用户确认percent或decimal。票面金额裸值默认元,表头或单元格明确“万元/亿元”时必须换算并记录来源。 - 对期限或金额异常,按 常识与合理性校验 分层处理:现行票据用“出票日→名义到期日不超过6个日历月”,不能把184天作为实际计息天数硬上限。金额常见区间仅提醒;超过默认10亿元核对阈值先澄清。缺少出票日时披露校验缺口,不把票号登记日当成出票日,也不凭常识自动改单位、金额或日期。
发现源表与票号明显冲突、关键值无法解析、关键字段缺失、同时匹配多列,或“票号+子票区间”业务键重复时,必须停止挑票和导出,向用户列出冲突及候选解释。使用负向市场分组或负向行别分级时,若本来可能入选的机构仍为待分类/无分类,也必须中断,提示可能的机构名笔误但不得自动纠正;用户可确认归类或明确排除待分类后继续。特别是“利率”“在库成本”等含义不唯一的表头,只有本次任务实际依赖时才阻断;纯挑票不因无关利率歧义停顿。用户确认后用字段映射或冲突策略记录选择,再继续流程。
快速工作流
默认快速路径
普通任务的首轮执行只做一次主流程调用:理解请求并构造 job 后,直接运行 scripts/run_bill_selection_workflow.py。一键流程会在同一次源表读取中完成表头映射、必要字段检查、唯一性检查、合理性校验、筛选、计算、导出和独立复算;返回 needs_clarification 时默认不创建结果文件。不要在首轮调用前重复人工读表、单独运行标准化脚本、运行多个 --help、搜索实现细节,或阅读 bill_selection_engine.py、prepare_bill_inventory.py、run_bill_selection_workflow.py 源码。
只有以下情况离开快速路径:一键流程返回 needs_clarification 时向用户询问;命令返回错误或结果与输入明显矛盾时进入诊断;用户明确要求审计、调试或解释实现时读取对应源码。诊断最多先做一次针对性检查,再重试一次;同一错误再次出现时报告阻断,不循环探查。
- 先判定新业务或同任务延续并确认可使用的要素来源;读取当前系统日期,从本任务有效请求中识别票据类型、正向/负向机构条件、承兑端/贴现端市场分组、跨年/足月/到期范围、单张金额、目标金额、排序目标、业务类型、成交利率、计息起始日和交付格式;把通用到期日排除条件显式写入 job。
- 按 常见业务模板 在内存中构造 job;只有字段结构确实不明时才读 输入结构。普通任务不要预读整个参考目录,也不要生成
normalized.csv、normalization.json或job.json。 - 执行任何脚本前,确认当前
SKILL.md所在目录的绝对路径SKILL_ROOT,以及实际运行解释器的绝对路径PYTHON_EXE。依赖检查、经授权的-m pip安装和业务脚本执行必须绑定同一个PYTHON_EXE。宿主同时提供基础 managed runtime 和已配置的任务 venv 时,使用该任务 venv,不因基础运行时带有 preferred 标签就切换环境。Windows venv 通常使用<venv>\Scripts\python.exe;宿主明确给出<envs>\default时才使用其Scripts\python.exe,不硬编码该布局,也不因bin/不存在而误判缺包。首次运行 XLS 前确认xlrd,首次运行 XLSX 或导出 XLSX 前确认openpyxl;缺失时读取requirements-spreadsheets.txt,未经授权不安装。同一会话复用已确认路径和检查结果,输入/输出格式未变化且解释器仍有效时不重复探测。具体 Windows 检查和调用方式见表格流程。 - 通过
--job-json或--job-stdin直接执行一次内存一键流程:
bash
"<PYTHON_EXE>" "<SKILL_ROOT>/scripts/run_bill_selection_workflow.py" --source "<source.xls>" --job-json '<含task_context的job JSON>' --require-task-context --output-dir "<output>"
三种任务入口互斥:--job-json 后面是 JSON 对象文本,不是文件名;--job-stdin 本身不带值,从标准输入读 JSON;--job <path.json> 只读取已有任务文件,不为普通运行新建中间文件。上例为 Bash 参数形式;Windows PowerShell 调用已确认路径用 & $billPython,包含中文或复杂引号的 JSON 优先由宿主进程 API 以 UTF-8 标准输入传递,示例见表格流程。字段映射、单位确认和冲突策略优先用 --field-map-json、--field-units-json、--conflict-policy-json 内联传入。仅在开发诊断时拆分标准化、引擎和导出步骤。
5. 严格按结果状态短路:needs_clarification 停止挑票/导出,不先做联网日历、版本或市场资料检查;若仅缺来源记录且本轮原文已经明确,由 Agent 补齐,真正缺失或有歧义的业务事实才展示问题向用户确认,再带确认参数重跑。ok 且 verification.status=passed 时直接使用顶层 selection、calculation、warnings、timings 和 artifacts 组织交付,不手工重复复算;failed、unverifiable 或命令错误才进入诊断。
6. 核对入选 ID、票数、票面总额、目标偏差、缺口/超额和必要计算合计后交付;明确本次是否计息,计息时披露实际日期、利率及其来源,说明明确沿用/默认值。task_context.status=recorded 和数学复算均不独立证明模型理解了本轮意图,不得声称完全排除上下文污染。用户复核已有结果时才单独运行 scripts/verify_result_workbook.py;一键流程已经通过内置独立复算的本次结果不要再次调用复核器。
默认不自动检查本 Skill 的软件版本;普通挑票、首次使用或新会话均不触发版本查询。只有用户明确要求“检查更新”等本 Skill 版本查询时,才按 Skill 版本检查 执行完整的来源查询流程,GitHub 仍作兜底。检查请求不等于安装授权;发现可信新版只提示,未经用户确认不得安装或覆盖正在运行的 Skill。此约定不改变业务所需的节假日日历核验。
按需读取
除下列触发条件外,不预读参考文件;首轮命令成功时不为解释脚本内部实现而补读源码。
- 涉及到期日、剩余天数或计息时,读取 节假日顺延。
calendar_status=preset表示已用预设节假日/调休规则,不等于日历不可用或仅覆盖局部;只有provisional_weekend_only表示相关日期缺少完整覆盖、按周末规则暂算。全表诊断含未入选行,不能将其告警套用到本次入选票;入选预设票仍须披露后续调整风险。 - 用户使用
O/N、隔夜、1D、7D、14D、1M—6M等期限代码时,读取 期限代码映射。 - 用户明确要求检查本 Skill 更新时,读取 Skill 版本检查;默认不读取或执行版本查询。
- 涉及双国、单国、国贴大商或机构分类时,读取 市场分类。
- 用户以银行简称、旧称或柜台说法指定具体机构时,读取 银行名称和柜台简称。
- 源表缺少票据类型、用户要求供票/非供票或票号与源表冲突时,读取 票号识别规则。
- 需要解释公式、审计计算或处理回购时,读取 业务规则。
- 表格结构不规则、需要源格式导出或验证工作簿时,读取 表格流程。
- 新增金额/期限阈值、遇到异常票面或超长期票时,读取 常识与合理性校验。
不可变规则
- 只生成分析和待复核清单,不执行、发送、确认或结算交易。
- 不修改或覆盖源文件,也不把完整票据池上传到网站、连接器或远程服务,除非用户明确授权具体目的地。
- 先应用版本化节假日日历得到实际到期日,再按日期筛选、排序和计息;源表实际到期日与日历结果冲突时先停止,由用户确认采用源表还是日历。
- 11 月及以后,涉及日期的任务主动核验当前年度调整和下一年度预设;其他月份只要本次任务所需年份缺失或仅部分覆盖,也必须触发一次缺口核验。业务字段、单位或含义尚未确认时先澄清,不提前联网;确认后向
update-status传入任务涉及的全部--required-year,再按返回计划依次检索官网、官微、全网,不预设新通知地址。同一会话中,日历文件 SHA256 和所需年份集合未变化时复用已完成的核验结果,不重复联网。只有完整且可核验为上海票据交易所发布的通知才能替换其明确适用的全年或局部预设范围;局部预设不得冒充全年日历。失败时继续使用本地日历并披露暂算范围。发现可靠新日历后提示用户更新 Skill,但不得静默改写已安装文件。 - 源表已有
market_label时原样保留;源表已有明确承兑行分级时优先采用并保留策略推断值供交叉核对。缺失时可使用带版本的 DeepFin 默认策略,但必须披露策略 ID/版本;替换策略按整份替换,不静默合并。 - 金额和利息使用
Decimal、ROUND_HALF_UP,日基数只允许 360 或 365。引擎内部利率是[0, 1)的小数,1.20% 表示为0.012。 - 票号和子票区间属于文本标识。检测到科学计数法或超过 Excel 15 位有效数字的数值型标识时必须停止,不能使用可能已失真的号码判断类型、供票或唯一性。
- 贴现/转贴现的名义到期日先顺延为实际到期日,再筛选和计息;回购到期日不自动顺延,显式或推算日期遇节假日均提示用户。回购到期日必须晚于首期结算日;期限明确后,先剔除实际到期日不晚于回购到期日的票,再排序组合。没有合格票时返回空结果,不执行计息。
- 金额组合使用可解释的
ranked-local-closest-v3局部优化算法,目标金额偏差优先,但不宣称全局最优;始终披露偏差、容差、候选总额和不足情况。 - 表格输入默认输出新的源表结构 XLSX:保留全部源列、表头、入选行值、公式、列序、数字格式、可见样式、列宽和行高,只在最后一列后追加必要结果字段。默认保持源行顺序,不增加装饰颜色、标题卡、额外工作表、表格、筛选器或合并单元格。
- 公式处理按需触发:无公式清单复用源工作簿读取,不加载公式缓存视图;有公式时,只对输入必需字段及实际导出的公式启动复算,详见表格流程。保留公式指保留计算语义:1.2.4起只自动导出可独立复算的同一源行数值公式,随记录搬移引用并验证结果及缓存;跨行、跨表、外部、命名引用或不支持的函数先阻断,不静默转值,也不把仅有公式文本快照的旧结果称为已验证。
- 确实生成了 XLSX 才能声称已生成;依赖不可用时交付 UTF-8 BOM CSV 并说明限制。
- 每次运行记录源文件、job、字段映射、单位确认、冲突策略、标准化票池、引擎代码、市场策略和节假日日历的 SHA256 审计指纹。指纹用于完整性与复现核对,不是数字签名。
输出要求
完全使用用户的语言作答。先给结果和清单,再简要说明:采用的筛选/排除条件、目标金额与实际金额、差额和是否候选不足、计息口径、日历/市场策略来源、近似组合说明、重要假设和仍需人工复核之处。源表格式优先于通用美化风格。
- 默认交付最终表格:实际挑票成功且有入选票据时,生成并交付一个包含全部入选记录的
挑票结果.xlsx,不要求用户另说“导出/下载”,也不因结果较少而省略。用户明确要求 CSV 时交付完整结果 CSV;明确不要文件时才仅在对话展示。不要把normalized.csv、normalization.json、result.json、候选池 CSV 或导出元数据作为默认交付物。 - 必须直接交付:最终回复在结果摘要旁主动附上宿主支持的表格附件或可点击获取该文件的链接,例如“下载挑票结果.xlsx”。使用本次执行返回的
artifacts中的真实文件,确认存在、可读取,并按宿主要求完成附件挂载;不能只报摘要、文件名、裸路径或“已生成”,也不能让用户自行到目录、文件面板或其他页面寻找文件/链接,或另行索要。 - 文件生成或交付失败时,说明具体原因及可行的下一步,不伪造附件/链接,也不声称已交付。澄清、执行失败或无入选票据时如实说明,不为满足交付要求伪造清单。
- 默认流程在内存中传递标准化、筛选、计算和导出数据,不生成也不删除过程文件。Agent 不得再执行
rm、Remove-Item、del等命令清理过程文件。 - 只有用户明确要求完整审计、诊断材料或过程数据时,才额外交付一个
挑票审计包.zip;不要散落多个过程文件。 - 出现阻断问题时,把问题、候选字段解释和必要诊断直接写在对话里;默认不留下诊断文件。
- 每次交付简要分析入选票据分布,至少包括最早/最晚实际到期日、最大/最小票面金额和平均剩余期限。执行利息或价差计算时,清单追加本次交易日、本次交易利率及实际使用的相关计算字段。
- 每次最终答复的最后一行固定、醒目地写成:AI生成内容,可能存在错误,请注意审核。该行之后不得再写其他内容。