请一个语言模型回答“球员A最近10场平均得分是多少”,它有两条路:凭对语言的记忆写出一个像样的数字,或者停下来,去数据库里查。前一条路只要几个字的生成时间,后一条路要先决定“去哪里查、查什么、怎么算”。体育大模型真正的分水岭就在这里:它是一个会说话的模型,还是一个会调用工具的系统。半岛体育大模型的设计思路是后者,聊天窗口只是入口,背后是一组各有职责的工具,以及一个负责“该调用谁”的调度环节。

一次调用的现场记录

先看一条简化的执行记录,想象用户问:“示例队乙换帅以后,前锋林某(虚构)的场均射门有变化吗?”系统的内部步骤大致如下,数据均为模拟。

  1. 规划:模型判断这是一个“时间切分 + 统计比较”的问题,需要先知道换帅日期,再比较前后两段比赛。
  2. 调用图查询工具:查询“示例队乙”的教练任期关系,返回新教练任职起始日期,例如2025-11-03。
  3. 调用SQL工具:以该日期为界,分别聚合林某前后两段的场次与射门数。
  4. 调用计算工具:计算两段的场均射门与差值,并检查两段场次是否足够。
  5. 调用可视化工具:选择合适的图形,把两段对比展示出来。
  6. 模型撰写答案:只使用前面返回的结果,写成人话,并附上口径与样本量。

整个过程里,模型没有一次是在“凭空回答”。它的工作是理解问题、决定顺序、把工具的输出翻译成解释,而所有数字都来自工具返回。这与把语言理解与统计计算拆开的原则一脉相承。

工具箱里有什么,各自不能做什么

工具 擅长 不该被用来
SQL 查询 过滤、排序、分组、聚合,例如最近N场均值查多跳关系路径;理解新闻文字
图数据库查询 实体之间的关系与时间区间,例如某教练任期内的球员流动 大批量数值聚合
文本检索 规则解释、报道、人物介绍等非结构化文本 回答需要精确统计的问题
计算器/统计引擎加权平均、百分位、差值、置信范围 决定该算什么
可视化引擎 按规则生成表格或图形 改变数据本身

每个工具都有明确边界,模型的责任是选择,工具的责任是保证自己那一段的正确性。两边职责越清楚,出错时越容易定位。关于SQL与图查询各自适合的场景,可以看Text-to-SQL与Text-to-Graph的对照。

五个选错工具的典型案例

工具调用听上去很稳妥,但“选错工具”本身就是一类新的错误。以下五种是设计评审里反复出现的情形。

案例一:用文本检索回答统计问题

用户问“球员A本赛季场均得分”。系统在文本库里检索到一篇赛季回顾,文中写了“他场均接近20分”,模型直接引用。问题是文章可能是赛季中段写的,数字已经过时,也可能是四舍五入的。凡是精确数值问题,工具选择规则规定必须走结构化数据,检索到的文章只能作为背景,不能充当数字来源。

案例二:用SQL硬凑多跳关系

“执教过示例队甲、后来又执教示例队乙的教练带过哪些共同的球员?”用SQL也能写,但需要多次自连接,条件稍复杂就容易漏。这类问题更适合交给图查询。选工具时,问题里“先……后来……再……”这类链式关系是一个强信号。

案例三:先算后查

模型有时会急于给出答案,在没拿到查询结果时就调用计算器,把自己猜的数字当作输入。校验层会检查计算工具的每个输入是否有来源标识:要么来自某次查询的返回,要么来自用户在问题里给出的数字,否则拒绝执行。

案例四:调用顺序错了

“换帅以后”这类问题,必须先取得日期,再用日期切分比赛。如果模型并行地调用两个工具,SQL那边拿到的是一个还不存在的日期参数,就会返回空结果或整段时间。系统用显式的依赖声明处理:后一个工具的输入必须引用前一个工具的输出,不满足就不能并行。

案例五:工具返回空,模型硬编

SQL返回0行,可能是球员别名没有被识别,也可能是时间窗口太窄。此时最糟的做法是让模型自己补一句“该球员近期表现平稳”。正确处理是把“空结果”当作一种一等状态:返回原因候选(实体未识别、时间无数据、口径过严),交给澄清环节,或者直接告诉用户没有查到。

调度环节的规则:不只是“让模型自己决定”

把调用哪个工具完全交给模型,短期看灵活,长期看容易漂移。半岛体育AI采用的思路是让模型提出计划,再由一层可检查的规则做审核。

plan:
  step 1: graph_query   -- 获取示例队乙教练任期
  step 2: sql_query     -- 依赖 step 1 的 start_date
  step 3: stat_compute  -- 依赖 step 2 的分组结果
  step 4: chart_select  -- 依赖 step 3 的场次与差值
check:
  - 每个数值必须来自某个 step 的输出
  - sql_query 必须带 season 或 date 范围
  - 结果行数为0时进入 clarify 分支,不进入 answer 分支

计划本身是可读的结构,审核规则是固定的。模型可以决定“这个问题要几步”,但不能绕过“数值必须有来源”这条线。

校验层:工具返回之后还要再看一眼

工具返回不等于可以直接使用,几类简单检查能挡住大部分低级错误。

  • 范围检查:场均得分为负数、命中率超过100%、上场时间超过一场比赛的可能时长,都属于明显异常。
  • 口径一致:前后两段用的统计口径要一致,比如都含加时,或者都不含。
  • 样本量提示:场次过少时,回答里必须带提示。
  • 时间截止:答案要写明数据截止日期,这是可追溯性的基础,详见答案证据链。

工具说明怎么写,决定模型会不会选对

模型是通过阅读工具说明来选择工具的,所以说明写得含糊,选择就会含糊。“查询体育数据”这样的描述几乎等于没写。更好的做法是把适用条件、输入字段、返回字段和禁止事项都写清楚,例如:

  • sql_query:输入为已解析的球员编号、日期范围和统计字段;返回为分组后的行与场次;不接受自然语言人名。
  • graph_query:输入为实体编号和关系类型,可带有效时间区间;返回为路径与每条边的起止时间;不做数值聚合。
  • text_search:返回带出处的段落;返回内容不得直接当作统计数值使用。

注意“不接受自然语言人名”这一条:球员身份必须在调用SQL之前就被解析成编号,这是实体识别环节的职责,而不是把一个名字字符串丢给数据库碰运气。同名球员这类问题,需要在更前面的实体识别环节解决。工具的输入类型越严格,模型犯错的空间越小,错误也越容易在入口处被拦下来,而不是流到最后一步才暴露。

工具失败的时候怎么办

工具不是永远可用的。查询可能超时,数据源可能某天没有更新,图数据库可能暂时返回不完整的路径。系统在设计时需要预先决定各类失败的处理方式,而不是让模型临场发挥。

  1. 可重试的失败:例如临时超时,可以在限定次数内重试,并且记录重试。
  2. 可降级的失败:图查询不可用时,如果问题允许,可以退回到只用SQL回答其中的统计部分,同时在答案中明确说明“关系部分未能核验”。
  3. 必须终止的失败:核心数据缺失时,宁可告诉用户“目前无法给出可靠答案”,也不用模型的语言记忆去补空。

每一次失败与降级都会写进调用记录,这样事后可以回看某个答案为什么只给了一半。用户看到的应该是诚实的不完整,而不是一个看上去完整实则拼凑的答案。

边界:工具再多,也有做不了的事

需要说清楚的是,工具调用不是万能钥匙。数据库里没有的数据,工具查不出来;数据库口径与用户预期不一致时,工具会准确地算出一个用户并不想要的数字;某些主观问题,比如“谁的比赛风格更漂亮”,没有工具能给出客观答案,系统应该说明这是价值判断,最多给出可以量化的部分。另外,静态官网上展示的只是产品设计与思路,半岛体育App与在线查询引擎属于规划中的能力,这里的示例都是说明流程的模拟场景,不代表已有大规模在线服务。

会聊天只是入口,会用工具才是本事

回到开头的问题:一个体育大模型该停下来去查数据,还是直接说出一个数字?答案取决于系统里有没有可用的工具、有没有对工具选择的约束,以及出错时是否有校验。语言能力决定回答读起来是否自然,工具与校验才决定答案能不能被信任。半岛体育大模型的设计重心也放在后者:让模型学会何时说“我去查一下”,并且在查回来之后,老老实实地只用查到的东西写答案。