对于招标文件,需要提炼里边的价格打分规则,然后计算。 问题:不同的项目计算规则不一致,只提炼价格打分...

Erstellt am: 17. Juli 2026

Beantwortet mit GPT-5.6 Thinking von Chat01

Frage

对于招标文件,需要提炼里边的价格打分规则,然后计算。
问题:不同的项目计算规则不一致,只提炼价格打分名称,然后调用已有代码计算不现实。让ai自动计算或者让ai自动写代码计算是否可行?,注意,使用的模型只是本地部署的32b小模型,是否有其他方法?

Gedanke

undefined

Gedanke

Providing a practical recommendation in Chinese

The architecture can be feasible without using AI to directly calculate arbitrary rules or generate code. A better approach is to have AI extract data into a constrained intermediate format, while using a deterministic evaluator for calculations. Human confirmation is essential for high-stakes decisions, and various schema fields can help implement this system efficiently.

Thought for 24s

Antwort

结论

可行,但不建议让本地 32B 模型直接完成最终计算,也不建议让它自由生成 Python/Java 代码后直接执行。

更稳妥的方案是:

AI 负责理解招标文件并提炼成结构化“价格评分规则”,确定性规则引擎负责计算。

也就是把问题从“识别价格打分名称”升级为:

识别完整的可执行语义:有效报价范围、基准价计算、分段条件、扣分公式、上下限、取整方式和异常处理。

本地 32B 模型通常足以承担“规则抽取、字段映射、异常提示”这类任务,但不应被当作精确计算器或无约束程序员。


为什么“名称 + 固定代码”不够

即使都叫“价格评分法”或“低价优先法”,实际差异可能包括:

  • 基准价是最低价、平均价、中位数,还是剔除极端值后的平均价;
  • 是否先排除无效报价、超过控制价的报价;
  • 高于基准价和低于基准价是否采用不同扣分系数;
  • 每偏离 1% 扣多少分,是否按不足 1% 计算;
  • 得分是否有最低值、最高值;
  • 中间结果和最终结果分别保留几位小数;
  • 是否存在随机抽取系数、下浮率或区间分支。

所以真正需要提炼的不是“规则名称”,而是一棵完整的规则表达式树


推荐架构

1. AI只负责生成“规则中间表示”

不要让模型输出自然语言结论:

本项目采用平均价作为基准价,每高出1%扣0.5分。

而是要求输出固定结构,例如:

json
{ "rule_type": "deviation_from_benchmark", "inputs": { "bid_price": "投标报价", "max_score": 30 }, "valid_bid_filter": { "exclude_over_control_price": true, "exclude_invalid_bids": true }, "benchmark": { "method": "arithmetic_mean", "source": "valid_bid_prices", "exclude_highest": 1, "exclude_lowest": 1 }, "score_formula": { "type": "piecewise", "branches": [ { "condition": "bid_price <= benchmark", "expression": "max_score - (benchmark-bid_price)/benchmark*100*0.3" }, { "condition": "bid_price > benchmark", "expression": "max_score - (bid_price-benchmark)/benchmark*100*0.5" } ] }, "limits": { "minimum_score": 0, "maximum_score": 30 }, "rounding": { "benchmark_digits": 2, "score_digits": 2, "mode": "half_up" }, "evidence": [ { "page": 35, "text": "投标报价每高于评标基准价1%,扣0.5分……" } ] }

然后由程序把这个结构交给统一计算引擎。

这样即使项目规则不同,计算程序本身也不需要针对每个项目重新编写,只需要解释不同的规则树。


2. 使用受限表达式,而不是任意代码

可以选择以下三类方式。

方案A:自定义价格评分 DSL

为招投标价格评分专门定义一套有限操作:

text
AVG(prices) MIN(prices) MAX(prices) MEDIAN(prices) REMOVE_HIGHEST(prices, 1) REMOVE_LOWEST(prices, 1) PERCENT_DIFF(price, benchmark) IF(condition, value1, value2) ROUND(value, digits) CLAMP(value, min, max)

模型只能从这些操作中组合。

这是最推荐的方式,因为招投标价格计算的运算类型相对有限,容易做安全检查和业务校验。

方案B:表达式引擎

让模型生成 CEL 或 JSON Logic,而不是 Python。

CEL 是非图灵完备、无副作用的嵌入式表达式语言,只能访问宿主程序明确提供的数据,适合安全执行公式和条件逻辑。(Common Expression Language)

JSON Logic 将规则表达为 JSON,支持算术、比较、条件、数组处理等操作,便于存储、审核和跨语言执行。(jsonlogic.com)

方案C:DMN决策表

对于大量分段条件,可以使用 DMN 决策表,例如:

条件计算
报价低于基准价每低1%扣0.3分
报价高于基准价每高1%扣0.5分
得分小于0按0分计算

DMN 是 OMG 制定的业务决策与规则建模标准,适合将业务规则表示为决策表和表达式。(omg.org)


不推荐直接让AI计算的原因

模型可以进行单次公式计算,但不适合作为最终计算引擎,主要风险是:

  1. 算术错误:尤其是多家报价、剔除最高最低值、分段扣分时。
  2. 规则遗漏:容易漏掉括号、前置条件、最低得分或取整规则。
  3. 每次结果不完全一致:相同输入可能因为生成过程产生不同解释。
  4. 难以审计:无法明确证明每一步结果对应哪条招标规定。
  5. 批量计算不稳定:几十或几百家投标人时,错误难以及时发现。

因此模型最多可以作为“第二计算通道”,与规则引擎结果进行对照,不应作为唯一计算通道。


是否可以让AI自动写代码

技术上可以,但应分为两种情况。

不建议:自由生成完整代码

例如让模型直接生成:

python
def calculate_score(...): ...

然后自动执行。

这种方式的问题是:

  • 可能误解规则;
  • 代码可能存在语法或逻辑错误;
  • 可能调用文件、网络或危险函数;
  • 每个项目生成不同实现,难以统一测试;
  • 代码看起来合理,但边界条件可能错误。

可以:生成受限代码片段或表达式

例如只允许模型输出:

text
CLAMP( max_score - IF( bid_price > benchmark, PERCENT_DIFF(bid_price, benchmark) * high_penalty, PERCENT_DIFF(bid_price, benchmark) * low_penalty ), 0, max_score )

系统再进行:

  • 语法解析;
  • 操作符白名单检查;
  • 变量完整性检查;
  • 类型检查;
  • 除零检查;
  • 边界测试;
  • 最终执行。

本地推理框架也可以通过 JSON Schema 或 grammar constrained decoding,强制模型输出符合结构的 JSON,而不是依赖提示词要求模型“尽量输出正确格式”。例如 llama.cpp 服务端支持 schema-constrained JSON 输出和工具调用。(GitHub)

但需要注意:

格式合法不代表规则理解正确。

因此结构化输出只能解决语法问题,不能代替业务校验。


适合32B本地模型的实际流程

第一阶段:定位规则

使用关键词、向量检索和章节结构共同定位:

  • 价格评分;
  • 报价得分;
  • 评标基准价;
  • 评标价;
  • 偏差率;
  • 扣分;
  • 控制价;
  • 有效报价;
  • 价格分值;
  • 算术平均值。

不要把整份几百页文件一次性发送给模型。应先通过目录、标题、关键词和向量检索,把范围缩小到相关页及其前后页。

第二阶段:原文提取

模型先输出:

  • 规则原文;
  • 页码;
  • 表格位置;
  • 引用的其他章节;
  • 可能影响计算的附加条件。

这一阶段暂时不要让模型生成公式。

第三阶段:规则结构化

第二次调用模型,将已定位的原文转换为统一规则结构。

建议采用“先分析、后封装”的两步方式:

  1. 第一次允许模型解释规则和指出歧义;
  2. 第二次通过 JSON Schema 强制输出规则对象。

这样通常比要求模型一次性“阅读、推理、生成严格 JSON”更稳。

第四阶段:静态校验

程序自动检查:

  • 基准价是否有定义;
  • 所有公式变量是否有来源;
  • 是否存在除以零;
  • 分段条件是否覆盖完整;
  • 分段条件是否互相冲突;
  • 得分是否可能超过满分;
  • 是否缺少最低得分;
  • 百分数的单位是 1 还是 0.01
  • 是每偏差“1%”扣分,还是偏差率直接乘系数;
  • 取整发生在中间步骤还是最终步骤。

第五阶段:自动生成测试用例

系统根据规则自动测试:

  • 报价等于基准价;
  • 报价略高于基准价;
  • 报价略低于基准价;
  • 报价等于控制价;
  • 报价超过控制价;
  • 只有一家有效报价;
  • 两家报价相同;
  • 剔除最高最低值后数据为空;
  • 计算结果为负数;
  • 计算结果超过满分。

模型可以负责提出测试场景,但具体数值和预期结果应由确定性程序计算。

第六阶段:人工确认规则,不逐项确认计算

在正式计算前,向业务人员展示:

text
基准价: 剔除1个最高价和1个最低价后,对剩余有效报价取算术平均值。 报价低于基准价: 每低1%扣0.3分。 报价高于基准价: 每高1%扣0.5分。 最低得分: 0分。 最终得分: 四舍五入保留2位小数。

旁边同时展示原文和页码。

用户只需要确认一次“规则解释是否正确”,之后所有投标人的得分都由程序统一计算。


建议采用“模板库 + 通用表达式”双层模式

纯模板无法覆盖所有项目,纯自由表达式又不够稳定。可以组合使用。

第一层:常见规则模板

建立模板库,例如:

  • 最低价满分,其他报价按比例得分;
  • 基准价满分,按偏差率扣分;
  • 高于和低于基准价采用不同扣分系数;
  • 有效报价平均值作为基准价;
  • 剔除最高最低报价后取平均值;
  • 按报价区间分段赋分;
  • 价格分由多个子项组成;
  • 随机系数或下浮系数参与基准价计算。

模型先判断是否能够匹配模板,再提取参数。

第二层:表达式树兜底

无法匹配模板时,模型生成通用表达式树:

json
{ "op": "max", "args": [ 0, { "op": "subtract", "args": [ {"var": "max_score"}, { "op": "multiply", "args": [ { "op": "divide", "args": [ { "op": "abs", "args": [ { "op": "subtract", "args": [ {"var": "bid_price"}, {"var": "benchmark"} ] } ] }, {"var": "benchmark"} ] }, 100, {"var": "penalty_per_percent"} ] } ] } ] }

这样既能覆盖常见规则,也能够处理少量特殊规则。


对32B模型的定位

建议让本地 32B 模型承担:

  • 相关章节定位;
  • 规则原文抽取;
  • 字段识别;
  • 规则模板分类;
  • 参数填充;
  • 表达式树生成;
  • 歧义识别;
  • 原文与结构化规则的一致性复核;
  • 生成测试场景。

不建议让它承担:

  • 最终批量数值计算;
  • 自由生成并直接执行程序;
  • 独立判断所有报价是否有效;
  • 在没有原文证据时补全规则;
  • 对歧义条款自行选择一种解释。

最终推荐

最适合这一场景的技术路线是:

text
文档解析/OCR 价格评分章节检索 32B模型抽取原文和规则字段 模板匹配 ├── 匹配成功:填充模板参数 └── 匹配失败:生成受限表达式树 语法、变量、边界和冲突校验 人工确认规则摘要及原文依据 确定性规则引擎批量计算 生成逐步计算过程和审计报告

核心原则是:

让AI写“规则数据”,不要让AI直接写并执行任意代码;让AI解释规则,不要让AI承担最终算术。

这种方案不要求模型特别大。相比更换更大模型,规则 DSL、结构化输出、确定性计算、原文证据和校验机制对整体准确率的提升通常更关键。

Frage

注意:规则无法确定,不同的招标文件规则都不一致

Gedanke

Thought for a couple of seconds

Antwort

理解。你的核心约束不是“规则类型很多”,而是:

事先无法知道规则长什么样,甚至无法建立完整模板库。

这种情况下,固定模板只能覆盖一部分,不能作为主方案。但仍然可以做,只是要把系统设计成“动态生成计算逻辑”,并接受一个现实:

规则可以自动解析和计算,但不能保证所有招标文件都完全无人审核。

关键要区分两种“无法确定”。

一、规则无法预先确定,但文件内描述明确

例如每个项目公式不同,但招标文件中明确写出了:

  • 哪些报价参与计算;
  • 怎样剔除异常报价;
  • 基准价怎么算;
  • 偏差率怎么算;
  • 不同区间怎样扣分;
  • 保留几位小数。

这种情况适合动态处理。不要预先定义“价格评分法有哪几种”,而是定义一套更底层的计算能力,让模型把自然语言规则编译成计算流程。

例如底层只提供这些通用原子操作:

text
筛选 排序 求和 平均值 加权平均 最大值 最小值 中位数 剔除前N个 剔除后N个 百分比计算 绝对值 四舍五入 向上取整 向下取整 条件判断 分段计算 上下限约束 循环处理投标人

招标文件的规则再特殊,通常也是这些原子操作的组合。

模型不需要判断它属于哪种“评分法”,而是直接输出计算步骤。例如:

json
{ "steps": [ { "id": "valid_bids", "operation": "filter", "source": "bids", "condition": { "and": [ {"field": "is_valid", "eq": true}, {"field": "price", "lte": {"var": "control_price"}} ] } }, { "id": "sorted_prices", "operation": "sort", "source": "valid_bids", "field": "price", "order": "ascending" }, { "id": "remaining_prices", "operation": "slice", "source": "sorted_prices", "remove_first": 1, "remove_last": 2 }, { "id": "benchmark", "operation": "average", "source": "remaining_prices", "field": "price" }, { "id": "score", "operation": "piecewise", "branches": [ { "when": {"price": {"lte": {"var": "benchmark"}}}, "expression": "30-(benchmark-price)/benchmark*100*0.2" }, { "when": {"price": {"gt": {"var": "benchmark"}}}, "expression": "30-(price-benchmark)/benchmark*100*0.5" } ] } ] }

这里没有预设具体评分规则,只预设了计算语言。


二、招标文件本身规则不明确

例如文件中存在这些情况:

  • 公式只写了一半;
  • 表格和正文冲突;
  • “偏差1%扣0.5分”,但没说明不足1%是否按比例;
  • 没说明中间结果如何取整;
  • 一个章节说剔除最高价,另一个章节又说所有有效报价参与;
  • 引用了附件,但附件缺失;
  • 公式来自扫描图片,识别不完整。

这种情况不是模型大小能解决的。

无论是32B、70B还是更大模型,都只能“猜”。系统必须输出:

json
{ "status": "ambiguous", "issues": [ { "type": "rounding_rule_missing", "description": "文件未说明偏差率计算结果的保留位数", "evidence_pages": [35, 36] }, { "type": "conflicting_rules", "description": "第35页要求剔除最高报价,第42页要求所有有效报价参与", "evidence_pages": [35, 42] } ] }

此时应停止自动计算,要求人工确认,而不是让AI自动选择一种理解。


对你的场景,真正可行的三种方案

方案一:AI生成通用计算流程

这是首选方案。

模型输出的不是规则名称,也不是固定模板编号,而是一套有顺序、有依赖关系的计算步骤。

类似数据库查询计划:

text
输入数据 → 筛选有效报价 → 判断投标人数量 → 根据数量选择剔除规则 → 计算平均值 → 乘调整系数 → 得出基准价 → 逐个计算偏差率 → 按区间计算得分 → 执行得分上下限 → 取整

这种方法能支持大量未知规则。

难点不是计算,而是模型能否正确把自然语言转换成流程。因此需要:

  • 每一步都引用招标文件原文;
  • 每个变量都标明来源;
  • 禁止模型自行补全缺失条件;
  • 输出不确定项;
  • 执行前进行静态检查。

方案二:AI动态生成代码,但必须受控

规则足够复杂时,通用 DSL 可能表达困难,例如:

  • 根据有效投标人数量采用不同剔除比例;
  • 按排名动态选择若干报价;
  • 多轮计算基准价;
  • 存在复杂的条件嵌套;
  • 多个价格子项分别评分再汇总。

这种情况下可以让AI生成代码,但不能直接信任和执行。

建议流程是:

text
招标规则原文 → AI生成纯计算函数 → 静态语法检查 → 安全检查 → 自动生成测试数据 → 第二次模型审查 → 沙箱运行 → 与人工样例核对 → 正式批量计算

生成的函数必须受到限制,例如:

python
def calculate_price_scores( bids: list[Bid], control_price: Decimal, parameters: dict ) -> list[ScoreResult]: ...

禁止:

  • 文件读写;
  • 网络访问;
  • 系统调用;
  • 动态导入;
  • evalexec
  • 反射;
  • 无限循环;
  • 非白名单第三方库。

数值类型应使用 Decimal,不能使用普通浮点数。

这种方式的覆盖能力最高,但审计和验证成本也最高。


方案三:LLM生成程序,符号执行或多路径验证

对于风险较高的项目,可以将AI生成的规则进行多路验证:

路径A:规则引擎计算

模型生成结构化规则,由规则引擎执行。

路径B:生成独立代码计算

模型基于同一原文生成另一份独立实现。

路径C:模型手工解释少量样例

选择3到5组边界输入,让模型逐步说明。

只有三个结果一致,才进入正式计算。

例如测试:

text
报价 = 基准价 报价 = 基准价 × 0.99 报价 = 基准价 × 1.01 报价 = 控制价 报价 = 控制价以上

这不能证明规则一定正确,但可以明显降低实现错误。


32B小模型能不能完成

可以完成相当一部分,但应把任务拆开,不能一次要求它:

阅读完整文件、找规则、理解公式、生成代码、执行计算并输出结果。

这对32B模型负担太大。

应拆成多个独立步骤。

第一次:定位相关内容

只做一件事:

text
找出所有可能影响价格评分的条款、表格、公式和引用章节。

第二次:整理变量

text
识别输入数据、常量、计算中间变量和最终输出。

示例:

json
{ "inputs": [ "投标报价", "最高投标限价", "有效投标人数量" ], "constants": [ "价格满分30分", "高于基准价每1%扣0.5分" ], "intermediate_variables": [ "有效报价集合", "评标基准价", "报价偏差率" ] }

第三次:生成步骤

只根据已确认的原文和变量生成计算步骤。

第四次:反向解释

把生成的步骤重新翻译成人类可读规则,并逐条与原文对照。

第五次:生成测试用例

让模型专门寻找边界条件,而不是继续修改代码。

任务拆开后,本地32B模型的可靠性会明显高于单次调用。


不要试图建立“完整规则模板库”

你说得对,不同招标文件规则都不一致,因此不存在一个能够提前覆盖所有情况的模板库。

但是仍然可以建立两类有限集合。

第一类:计算原子是有限的

虽然规则无限组合,但基本运算通常有限:

text
筛选、排序、聚合、比例、分段、取整、上下限、排名、剔除、加权。

类似编程语言不需要预先知道未来所有程序,只需要提供足够的语法和运算符。

第二类:常见歧义类型是有限的

例如:

  • 有效报价定义缺失;
  • 百分数单位不明确;
  • 剔除数量不明确;
  • 边界值归属不明确;
  • 取整顺序不明确;
  • 条款冲突;
  • 引用内容缺失;
  • 投标人数不足时无处理方式。

可以建立“规则完整性检查器”,不需要提前知道具体评分规则。


建议系统采用三个状态

不要只有“解析成功”和“解析失败”。

1. 可自动执行

json
{ "status": "executable", "confidence": 0.93 }

满足:

  • 输入明确;
  • 条件完整;
  • 公式完整;
  • 边界清晰;
  • 无冲突;
  • 所有变量都有来源。

2. 需要人工确认

json
{ "status": "needs_confirmation", "questions": [ "不足1%的偏差是否按比例扣分?", "基准价计算结果是否先保留两位小数?" ] }

模型已经基本理解规则,但存在局部不确定性。

3. 无法执行

json
{ "status": "not_executable", "reason": "评分公式引用附件3,但当前文件中未包含附件3" }

这种状态不能继续计算。


最现实的落地方案

建议采用:

text
文档解析 相关条款全量定位 LLM提取规则事实和原文证据 LLM生成动态计算流程 程序进行完整性和一致性检查 LLM反向解释计算流程 人工只确认歧义和复杂规则 沙箱或规则引擎执行 输出每一步计算明细

每个得分结果应能展开为:

text
投标报价:9,800,000元 评标基准价:10,000,000元 偏差率:(10,000,000 - 9,800,000) / 10,000,000 × 100% = 2% 扣分:2 × 0.3 = 0.6分 价格得分:30 - 0.6 = 29.4分 原文依据:第35页第4.2.3条

最终判断

在“规则完全无法预先确定”的前提下:

  • 固定代码调用不可行;
  • 仅提取规则名称不可行;
  • 完全依赖32B模型直接计算,风险很高;
  • 让32B模型自由写代码并自动执行,也不适合直接上线;
  • 动态生成受限计算流程,配合校验、沙箱和人工确认,是可行方案。

本质上,应把本地模型当作一个“招标规则编译器前端”:

自然语言招标条款 → 中间计算表示 → 校验 → 确定性执行

而不是把它当作最终计算器。

Diesen Q&A teilen