Product chose A after the A/B: low cut answer-step reasoning tokens ~45% and answer time 34s -> 22s with no quality loss. Unset now means "low"; CONSULT_ANSWER_REASONING_EFFORT=off restores the pre-change request body, and the old "unset keeps the body" guarantee moves to "off". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
152 lines
5.8 KiB
TypeScript
152 lines
5.8 KiB
TypeScript
/**
|
|
* Answer-step reasoning effort (issue #65).
|
|
* The unset bodies were captured before this switch read the environment:
|
|
* node node_modules/tsx/dist/cli.mjs tests/answer-effort-probe.mts --dry-run --save-baseline
|
|
*/
|
|
import assert from "node:assert/strict";
|
|
import { readFileSync } from "node:fs";
|
|
import test from "node:test";
|
|
|
|
import {
|
|
consultAnswerReasoningEffort,
|
|
consultationContinueGenerationSettings,
|
|
consultationGeneralPrepareStep,
|
|
consultationGenerationSettings,
|
|
consultationNatalPrepareStep,
|
|
} from "../src/mastra/consultation-tools.ts";
|
|
import { captureStreamBodies } from "./answer-effort-probe.mts";
|
|
|
|
const MODEL = {
|
|
providerId: "deepseek",
|
|
modelId: "deepseek-flash",
|
|
url: "http://127.0.0.1:9/v1",
|
|
apiKey: "dummy",
|
|
};
|
|
|
|
const fixture = JSON.parse(readFileSync(new URL("./fixtures/answer-effort-switch-20261013.json", import.meta.url), "utf8")) as {
|
|
natal: unknown[];
|
|
continue: unknown[];
|
|
};
|
|
|
|
function withoutEffort(body: unknown) {
|
|
const copy = { ...(body as Record<string, unknown>) };
|
|
delete copy.reasoning_effort;
|
|
return copy;
|
|
}
|
|
|
|
test("an illegal effort warns once and stays unset", () => {
|
|
const previous = process.env.CONSULT_ANSWER_REASONING_EFFORT;
|
|
const seen: unknown[][] = [];
|
|
const warn = console.warn;
|
|
console.warn = (...args: unknown[]) => { seen.push(args); };
|
|
process.env.CONSULT_ANSWER_REASONING_EFFORT = "turbo";
|
|
try {
|
|
assert.equal(consultAnswerReasoningEffort(), undefined);
|
|
assert.equal(consultAnswerReasoningEffort(), undefined);
|
|
assert.equal(seen.length, 1);
|
|
} finally {
|
|
console.warn = warn;
|
|
if (previous === undefined) delete process.env.CONSULT_ANSWER_REASONING_EFFORT;
|
|
else process.env.CONSULT_ANSWER_REASONING_EFFORT = previous;
|
|
}
|
|
});
|
|
|
|
// 原值: 不设环境变量时请求体与改动前逐字节相同
|
|
// 新值: 设成 "off" 时请求体与改动前逐字节相同;不设时默认 "low"(见下一条)
|
|
// 原因: issue #134 产品选 A,答题步默认低思考量;"off" 是一行回退
|
|
test("off keeps the pre-change request bodies", async () => {
|
|
const previous = process.env.CONSULT_ANSWER_REASONING_EFFORT;
|
|
process.env.CONSULT_ANSWER_REASONING_EFFORT = "off";
|
|
try {
|
|
const natal = await captureStreamBodies({
|
|
settings: consultationGenerationSettings(MODEL),
|
|
prepareStep: (input) => consultationNatalPrepareStep({
|
|
stepNumber: input.stepNumber,
|
|
answerReady: input.stepNumber >= 1,
|
|
model: MODEL,
|
|
}),
|
|
steps: 2,
|
|
});
|
|
const continued = await captureStreamBodies({
|
|
settings: consultationContinueGenerationSettings(MODEL),
|
|
steps: 1,
|
|
});
|
|
assert.deepEqual(natal, fixture.natal);
|
|
assert.deepEqual(continued, fixture.continue);
|
|
} finally {
|
|
if (previous === undefined) delete process.env.CONSULT_ANSWER_REASONING_EFFORT;
|
|
else process.env.CONSULT_ANSWER_REASONING_EFFORT = previous;
|
|
}
|
|
});
|
|
|
|
test("unset or blank effort defaults to low", () => {
|
|
const previous = process.env.CONSULT_ANSWER_REASONING_EFFORT;
|
|
try {
|
|
delete process.env.CONSULT_ANSWER_REASONING_EFFORT;
|
|
assert.equal(consultAnswerReasoningEffort(), "low");
|
|
process.env.CONSULT_ANSWER_REASONING_EFFORT = " ";
|
|
assert.equal(consultAnswerReasoningEffort(), "low");
|
|
process.env.CONSULT_ANSWER_REASONING_EFFORT = "off";
|
|
assert.equal(consultAnswerReasoningEffort(), undefined);
|
|
} finally {
|
|
if (previous === undefined) delete process.env.CONSULT_ANSWER_REASONING_EFFORT;
|
|
else process.env.CONSULT_ANSWER_REASONING_EFFORT = previous;
|
|
}
|
|
});
|
|
|
|
test("unset effort puts low on the answer step only", async () => {
|
|
const previous = process.env.CONSULT_ANSWER_REASONING_EFFORT;
|
|
delete process.env.CONSULT_ANSWER_REASONING_EFFORT;
|
|
try {
|
|
const natal = await captureStreamBodies({
|
|
settings: consultationGenerationSettings(MODEL),
|
|
prepareStep: (input) => consultationNatalPrepareStep({
|
|
stepNumber: input.stepNumber,
|
|
answerReady: input.stepNumber >= 1,
|
|
model: MODEL,
|
|
}),
|
|
steps: 2,
|
|
}) as Record<string, unknown>[];
|
|
assert.deepEqual(natal[0], fixture.natal[0]);
|
|
assert.equal(natal[1]?.reasoning_effort, "low");
|
|
assert.deepEqual(withoutEffort(natal[1]), fixture.natal[1]);
|
|
} finally {
|
|
if (previous === undefined) delete process.env.CONSULT_ANSWER_REASONING_EFFORT;
|
|
else process.env.CONSULT_ANSWER_REASONING_EFFORT = previous;
|
|
}
|
|
});
|
|
|
|
test("low effort is only on the answer step", async () => {
|
|
const previous = process.env.CONSULT_ANSWER_REASONING_EFFORT;
|
|
process.env.CONSULT_ANSWER_REASONING_EFFORT = "low";
|
|
try {
|
|
const natal = await captureStreamBodies({
|
|
settings: consultationGenerationSettings(MODEL),
|
|
prepareStep: (input) => consultationNatalPrepareStep({
|
|
stepNumber: input.stepNumber,
|
|
answerReady: input.stepNumber >= 1,
|
|
model: MODEL,
|
|
}),
|
|
steps: 2,
|
|
}) as Record<string, unknown>[];
|
|
assert.equal(natal[0]?.reasoning_effort, undefined);
|
|
assert.deepEqual(natal[0], fixture.natal[0]);
|
|
assert.equal(natal[1]?.reasoning_effort, "low");
|
|
assert.deepEqual(withoutEffort(natal[1]), fixture.natal[1]);
|
|
const continued = await captureStreamBodies({
|
|
settings: consultationContinueGenerationSettings(MODEL),
|
|
steps: 1,
|
|
});
|
|
assert.deepEqual(continued, fixture.continue);
|
|
const daily = await captureStreamBodies({
|
|
settings: consultationGenerationSettings(MODEL),
|
|
prepareStep: (input) => consultationGeneralPrepareStep({ stepNumber: input.stepNumber, model: MODEL }),
|
|
steps: 1,
|
|
}) as Record<string, unknown>[];
|
|
assert.equal(daily[0]?.reasoning_effort, "low");
|
|
} finally {
|
|
if (previous === undefined) delete process.env.CONSULT_ANSWER_REASONING_EFFORT;
|
|
else process.env.CONSULT_ANSWER_REASONING_EFFORT = previous;
|
|
}
|
|
});
|