mirror of
https://github.com/langgenius/dify.git
synced 2026-09-05 08:48:10 +08:00
fix(knowledge-fs): constrain research graph planning
This commit is contained in:
parent
8096e61133
commit
63cfebbef3
@ -1,6 +1,6 @@
|
||||
{
|
||||
"schemaVersion": 5,
|
||||
"subtreeTree": "0739e3faf3861c45e78beb693edcd7e9d6550c1f",
|
||||
"subtreeTree": "cd6c4687eaafa5e178c79aaa52c88869666f36b4",
|
||||
"openapiSha256": "2cf348c68bbe65dd51bbde9a0a4f91398beeebd79e89e9288c9386b26ae09796",
|
||||
"capabilityV2AuthManifestSha256": "fc0a47e23cce12544882f0298522b4933002e892b84ce1815df7e81d36a7a0c7",
|
||||
"capabilityV2AuthTestVectorSha256": "ae0de37b1ff05c40f905cf17a7b410d8971acacf64db07d5ee3d6fecfa559ce3",
|
||||
|
||||
@ -83,11 +83,23 @@ describe("Research evidence reasoning", () => {
|
||||
subqueries: ["renewal terms", "termination terms"],
|
||||
});
|
||||
expect(generate).toHaveBeenCalledTimes(2);
|
||||
expect(generate.mock.calls[1]?.[0]).toMatchObject({
|
||||
structuredOutputSchema: {
|
||||
properties: {
|
||||
useGraph: { enum: ["false", "true"], type: "string" },
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it.each([
|
||||
{ expected: false, providerValue: "false" },
|
||||
{
|
||||
expected: false,
|
||||
providerValue: "不使用;这是按主题拆分的概览检索,不需要关系图或多跳推理。",
|
||||
},
|
||||
{ expected: true, providerValue: "true" },
|
||||
{ expected: true, providerValue: "需要使用关系图完成多跳推理。" },
|
||||
])(
|
||||
"normalizes the structured-output string boolean useGraph=$providerValue",
|
||||
async ({ expected, providerValue }) => {
|
||||
|
||||
@ -403,7 +403,9 @@ function zodJsonSchema(schema: z.ZodTypeAny): Readonly<Record<string, unknown>>
|
||||
evidenceDimensions: { items: { type: "string" }, maxItems: 6, type: "array" },
|
||||
intent: { enum: ["comparison", "direct", "multi-hop", "overview"], type: "string" },
|
||||
subqueries: { items: { type: "string" }, maxItems: 3, type: "array" },
|
||||
useGraph: { type: "boolean" },
|
||||
// Dify's structured-output compatibility layer converts JSON Schema booleans to strings.
|
||||
// Constrain the string values here so the model cannot replace a boolean with prose.
|
||||
useGraph: { enum: ["false", "true"], type: "string" },
|
||||
},
|
||||
required: ["evidenceDimensions", "intent", "subqueries", "useGraph"],
|
||||
type: "object",
|
||||
@ -444,7 +446,7 @@ function parseQueryPlan(text: string): z.infer<typeof QueryPlanSchema> {
|
||||
// Dify's structured-output compatibility layer represents JSON Schema booleans as strings
|
||||
// for providers that do not accept native boolean fields. Normalize that transport detail
|
||||
// before applying the strict domain schema, just as the evidence judge does below.
|
||||
const useGraph = normalizeBooleanValue(record.useGraph);
|
||||
const useGraph = normalizeUseGraphValue(record.useGraph);
|
||||
if (useGraph !== undefined) {
|
||||
value = { ...record, useGraph };
|
||||
}
|
||||
@ -542,6 +544,29 @@ function normalizeBooleanValue(value: unknown): boolean | undefined {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function normalizeUseGraphValue(value: unknown): boolean | undefined {
|
||||
const normalizedBoolean = normalizeBooleanValue(value);
|
||||
if (normalizedBoolean !== undefined || typeof value !== "string") {
|
||||
return normalizedBoolean;
|
||||
}
|
||||
const normalized = value.trim().toLocaleLowerCase();
|
||||
if (
|
||||
/^(?:do not use|don't use|not needed|unnecessary|不使用|不要使用|无需|不需要|不启用)(?:\s|关系图|图谱|图|[.,,。::;;]|$)/u.test(
|
||||
normalized,
|
||||
)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
if (
|
||||
/^(?:use|should use|need to use|enabled|使用|应使用|需要使用|启用|开启)(?:\s|关系图|图谱|图|[.,,。::;;]|$)/u.test(
|
||||
normalized,
|
||||
)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function modelFailureIsRetryable(error: unknown): boolean {
|
||||
if (error && typeof error === "object" && "retryable" in error) {
|
||||
return (error as { readonly retryable?: unknown }).retryable === true;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user