Qwen 已返回 `tool_calls`,为什么你的行情回答仍可能不可信?

摘要:

Qwen 返回 tool_calls,不代表行情查询已经成功。本文从掘金开发者常见排错场景出发,拆解"触发工具、应用执行、结果校验、工具回填、最终回答"的最小可信链路,并给出未触发工具、查询失败或空结果、回填错误三个必须阻断价格回答的失败分支。TickDB 仅作为应用端只读行情数据路径示例出现。

你在日志里看到了这样的返回:

json 复制代码
{
  "tool_calls": [
    {
      "function": {
        "name": "get_market_snapshot",
        "arguments": "{\"symbol\":\"AAPL.US\"}"
      }
    }
  ]
}

这只能说明一件事:模型提出了一个工具调用请求。

它不等于应用程序已经拿到行情,不等于返回内容有效,也不等于最终回答确实基于这次查询结果生成。对于"当前价格是多少"这类问题,只要工具链路没有完整闭环,模型就不应该继续输出确定价格。

tool_calls 不是行情结果

百炼官方文档给出的 Function Calling 流程,本质上由应用程序完成闭环:

步骤 发生了什么 能否证明行情可信
1 应用把用户问题和工具定义发给 Qwen 不能
2 Qwen 返回工具名称与参数,即 tool_calls 不能
3 应用实际执行只读行情查询 仍需检查结果
4 应用把工具输出作为 role="tool" 消息回填 形成回答依据
5 应用再次请求 Qwen 生成自然语言答案 仅在前面成功时可回答

容易忽略的是第 3、4 步:真正访问行情数据的是你的应用,而不是 tool_calls 本身。

最小可信调用链路

对于必须依赖当前行情的数据问题,可以把链路收紧为以下五步:

环节 最小要求 失败时的动作
识别问题 判断请求是否必须读取当前行情 不能把静态知识当当前价格
触发工具 对已确认需要行情的分支要求工具调用 未触发则停止报价格
执行查询 应用调用只读行情适配器,例如接入 TickDB REST 查询快照 请求失败或空结果则停止
回填证据 将成功结果绑定原始 tool_call_id 回填给模型 未正确回填则停止
生成回答 仅基于工具返回组织自然语言 不扩展为交易判断

这里 TickDB 的位置很简单:它可以是应用端行情适配器实际查询的数据路径之一。Qwen 负责决定要调用什么工具并整理回答,应用负责执行和校验查询,两者不能混写成"模型自己知道行情"。

核心代码片段:重点在阻断条件

以下为教学用核心片段,不是完整可运行代码。Qwen 的 OpenAI 兼容调用形式依据百炼官方文档;query_snapshot_via_readonly_adapter() 为故意省略的应用端执行器,可在审核后接入并核验 TickDB REST 请求、鉴权、字段与异常处理。

python 复制代码
import json
import os
from openai import OpenAI

client = OpenAI(
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
)

tools = [{
    "type": "function",
    "function": {
        "name": "get_market_snapshot",
        "description": "读取指定标的的当前行情快照,只用于只读查询。",
        "parameters": {
            "type": "object",
            "properties": {"symbol": {"type": "string"}},
            "required": ["symbol"],
        },
    },
}]

messages = [{"role": "user", "content": "查询 AAPL.US 当前价格"}]
first = client.chat.completions.create(
    model="qwen3.6-plus",
    extra_body={"enable_thinking": False},
    messages=messages,
    tools=tools,
    tool_choice="required",  # 仅用于已确认必须查行情的分支
)

assistant_msg = first.choices[0].message
if not assistant_msg.tool_calls:
    raise RuntimeError("未触发行情工具,禁止输出当前价格")

messages.append(assistant_msg)
call = assistant_msg.tool_calls[0]
args = json.loads(call.function.arguments)

# 应用端只读数据适配器:可接 TickDB REST;此处省略真实网络实现。
result = query_snapshot_via_readonly_adapter(args)

if not result.get("ok") or not result.get("quote"):
    raise RuntimeError("查询失败或无可验证行情,禁止输出当前价格")

messages.append({
    "role": "tool",
    "tool_call_id": call.id,
    "content": json.dumps(result, ensure_ascii=False),
})

final = client.chat.completions.create(
    model="qwen3.6-plus",
    extra_body={"enable_thinking": False},
    messages=messages,
    tools=tools,
)  # 总结工具结果阶段,不继续强制工具调用
print(final.choices[0].message.content)

片段里的关键不是函数名,而是三条规则:

  1. 没有真实工具结果,就没有当前价格结论。
  2. 工具失败或结果为空,应该明确告诉用户"当前无法验证",而不是让模型补写一个价格。
  3. 工具结果必须绑定正确的 tool_call_id 回填,之后的回答才有证据来源。

至少三个常见失败分支

失败分支 你会看到什么 为什么不可信 正确处理
未触发工具 模型直接返回一段价格回答,tool_calls 为空 没有任何实时查询证据 对行情查询分支要求调用工具;仍无调用则停止输出价格
工具请求失败或返回空结果 超时、权限失败、适配器报错,或返回无可用行情 有调用意图,但没有可消费的数据 返回"行情暂不可验证",记录错误,不进入价格总结
结果未被正确回填 应用拿到了数据,却没有添加 role="tool" 消息,或绑定错 tool_call_id 最终模型上下文里没有对应证据 保留原始 assistant 工具调用消息,按调用 ID 回填结果后再请求总结
结果存在但回答越界 工具只返回快照,模型却继续输出买卖判断或价格预测 数据查询不等于决策依据 限制回答范围,只描述查询结果与可验证边界

一个更实用的验收清单

上线前,不妨对行情工具调用链逐项检查:

  • 当前行情问题是否被路由到必须查询工具的分支。
  • tool_calls 是否只被视为请求,而不是查询成功标志。
  • 应用端查询是否为只读操作,并处理失败、超时和空结果。
  • 返回值是否作为工具消息正确回填到对应调用。
  • 最终回答是否只描述得到的数据,不补写不存在的结果。
  • 日志是否足以区分"模型没调工具""工具没数据""回填出错"三类问题。

边界说明

本文讨论的是工具调用链路的可信性设计,不提供交易建议,也不把一次行情快照扩展成趋势、收益或买卖判断。TickDB 在这里仅作为应用端可以接入的只读行情数据路径示例;实际接入时,仍应以当前接口文档和审核后的请求实现为准。

总结

看到 tool_calls,只能证明 Qwen 知道"该去查"。

只有应用成功执行查询、确认结果可用、正确回填工具输出,并让模型基于该结果回答,当前行情结论才拥有最基本的证据闭环。

对于行情类问答,最重要的工程规则不是"尽量回答",而是:没有可验证工具结果时,明确停止报价格。

标签:
Qwen Function Calling tool_calls Python API 行情查询 排错

阿里云百炼 Function Calling 官方文档

相关推荐
武子康2 分钟前
Java-07 深入浅出 MyBatis数据库一对多关系模型实战:表结构设计与查询实现
java·后端
花椒技术1 小时前
企业内部 Agent 落地复盘:Gateway、Skill 和二次确认如何串起受控业务执行
后端·agent·ai编程
Agent手记2 小时前
制造业生产流程自动化,Agent需要具备哪些能力?深度拆解2026工业级智能体落地范式与核心架构
大数据·人工智能·ai·架构·自动化
Yunzenn3 小时前
深度分析字节最新研究cola-DLM 第 07 章:推理流水线逐行拆解 —— 从 prompt 到生成文本
人工智能·驱动开发·深度学习·chatgpt·架构·prompt·github
我是一颗柠檬3 小时前
【MySQL全面教学】MySQL事务与ACID Day9(2026年)
数据库·后端·mysql
枕星而眠3 小时前
数据结构八大排序详解(一):四大简单排序
c语言·数据结构·c++·后端
IT_陈寒3 小时前
React useEffect闭包陷阱差点把我整失业了
前端·人工智能·后端
苍何3 小时前
爆肝两周,我把 Codex 最全实战指南开源了
后端
颖火虫盟主4 小时前
Linux 系统分层架构:从硬件通电到 systemd 进程管理
linux·运维·架构
bug菌4 小时前
【SpringBoot 3.x 第254节】夯爆了,数据库访问性能优化实战详解!
数据库·spring boot·后端