Skip to content

[Bug] Dify Cloud 检索接口 query 字段返回字符串,导致 DifyResponse 反序列化失败(kb_search 对 api.dify.ai 引用恒为空) #1917

Description

@mars171

背景

我们基于 agentscope-java 2.0.0-RC4 构建了一套智能体平台,通过 agentscope-extensions-rag-dify 接入 Dify 知识库做 RAG 检索(kb_search 工具)。本地用 stub/mock 的 Dify 响应(query 写成对象形态)联调时一切正常;但一旦切到**真实的 Dify Cloud(api.dify.ai)**知识库,kb_search 就完全失效——检索结果与引用恒为空。

问题现象

  • 对真实 Dify 知识库执行 kb_search(以及连接管理里的「连通测试」)时,后端抛 Failed to deserialize DifyResponse
  • 由于整个响应反序列化失败,检索到的 records 被整体丢弃,知识库引用恒为空,RAG 完全不可用。
  • 本地 stub(把 query 写成对象)不暴露此问题,只有连真实 Dify Cloud 才触发,隐蔽性较强。

根因

io.agentscope.core.rag.integration.dify.model.DifyResponse.Query 把响应里的 query 字段建模为对象

public static class Query {
    private String content;     // 仅默认构造 + getter/setter
    public String getContent() { return content; }
    public void setContent(String content) { this.content = content; }
}

它期望 query{"content":"..."}。但真实 api.dify.ai 返回的 query 是裸字符串。Jackson 无法把一个 JSON string 构造成 Query 对象,于是整个 DifyResponse 反序列化失败,连带丢弃所有 records。

我们的发现 / 排查过程(供参考)

  1. 最初怀疑是依赖版本或本地构建问题,逐一排除后,把范围锁定到 Dify 响应的反序列化环节。
  2. 我们翻了 Dify 官方 GitHub 源码 api/services/hit_testing_service.py,发现它构造响应时 query对象 {"content": query}compact_retrieve_response / compact_external_retrieve_response)。这一度让我们以为 agentscope 的 DTO 没问题、是别处的锅。
  3. 为了确认,我们实际调用了一次真实的 api.dify.ai 检索接口,结果发现线上服务返回的 query裸字符串,与 GitHub main 源码不一致(推测是 Dify Cloud 的部署版本与 main 分支存在差异,或外部 Service API 走了与 hit-testing 不同的序列化路径)。最终以线上实测为准。

复现步骤

调用 Dify Cloud 检索接口:

POST https://api.dify.ai/v1/datasets/{dataset_id}/retrieve
Authorization: Bearer {api_key}
Content-Type: application/json

{"query":"ping","retrieval_model":{"search_method":"semantic_search","top_k":1}}

实测响应(HTTP 200,已脱敏):

{
  "query": "ping",
  "records": [
    { "segment": { "id": "...", "content": "...", "position": 1, "document": { "id": "...", "name": "..." } }, "score": 0.9 }
  ]
}

注意顶层 query 是字符串 "ping"不是 {"content":"ping"}

影响范围

所有使用 Dify Cloud(api.dify.ai) 知识库的 agentscope-java 用户,kb_search 检索结果与引用恒为空,RAG 功能不可用。经核实 2.0.0-RC4 与最新 main 分支均未修复。

建议修复

DifyResponse.Query 增加一个委托模式(DELEGATING)的 @JsonCreator,并保留默认构造 + setter,使其同时兼容「字符串」与「对象」两种形态:

@JsonCreator(mode = JsonCreator.Mode.DELEGATING)
public static Query fromString(String content) {
    Query query = new Query();
    query.setContent(content);
    return query;
}

裸字符串走该工厂、对象形态走默认 bean,两种都不再报错。我们本地已用此方案验证可行(兼容两种 payload),乐意提交 PR。

最后

顺便恳请官方加快 2.0 正式版、尤其是知识库 / RAG 模块的发布节奏 🙏。目前还停留在 RC 阶段,而知识库是大量落地场景的刚需,希望能把这类「与真实 Dify Cloud 对接」的兼容性问题修好后尽快 GA 上架,让大家能放心把知识库能力用于生产环境。非常感谢维护者们的辛勤付出!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions