fix(agents): widen answer length limits and preserve followUp continuations

INTENT_MAX_ANSWER_LENGTH was too tight (objection_expression 200 chars truncated
good responses). Bumped all limits ~25-50%. Also fixed followUp filter that silently
dropped content when model split answer across answer+followUp fields — now appends
followUp as continuation when answer ends mid-sentence.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
hailin 2026-02-07 10:25:59 -08:00
parent 366a9cda3a
commit b55cd4bc1e
2 changed files with 23 additions and 11 deletions

View File

@ -369,10 +369,22 @@ export async function* agentLoop(
yield { type: 'text', content: answer, timestamp: Date.now() };
// followUp 必须是面向用户的问题(含?),过滤掉内部策略备注
if (parsed.followUp && /|\?/.test(parsed.followUp)) {
const followUp = smartTruncate(parsed.followUp, MAX_FOLLOWUP_LENGTH);
yield { type: 'text', content: '\n\n' + followUp, timestamp: Date.now() };
// followUp 处理:
// 1. 含 /? → 作为跟进问题输出
// 2. answer 未以句末标点结束 → followUp 可能是 answer 的延续部分,追加输出
// 3. 其余情况 → 过滤掉(内部策略备注等)
if (parsed.followUp) {
const isQuestion = /|\?/.test(parsed.followUp);
const answerEndsClean = /[。!?;!?]$/.test(answer.replace(/\.{3}$/, ''));
if (isQuestion) {
const followUp = smartTruncate(parsed.followUp, MAX_FOLLOWUP_LENGTH);
yield { type: 'text', content: '\n\n' + followUp, timestamp: Date.now() };
} else if (!answerEndsClean) {
// answer 被截断或模型将内容分到 followUp → 追加(不换行)
logger.debug(`[Turn ${currentTurn + 1}] followUp appended as answer continuation`);
yield { type: 'text', content: parsed.followUp, timestamp: Date.now() };
}
}
} else {
// JSON 合法但缺少 answer 字段 → yield 原始文本

View File

@ -29,13 +29,13 @@ export type CoordinatorResponse = z.infer<typeof CoordinatorResponseSchema>;
/** 每种意图对应的最大 answer 长度(字符数)— 程序级硬约束 */
export const INTENT_MAX_ANSWER_LENGTH: Record<string, number> = {
factual_question: 200, // 1-3句直接给答案
yes_no_question: 120, // 1-2句结论+理由
comparison_question: 250, // 2-3句推荐+理由
assessment_request: 400, // 按需但有上限
objection_expression: 200, // 共情+事实+引导
detailed_consultation: 500, // 复杂咨询允许较长
casual_chat: 80, // 1句
factual_question: 250, // 1-3句直接给答案
yes_no_question: 150, // 1-2句结论+理由
comparison_question: 300, // 2-3句推荐+理由
assessment_request: 500, // 按需但有上限
objection_expression: 350, // 共情+事实+引导3个组件各需空间
detailed_consultation: 600, // 复杂咨询允许较长
casual_chat: 100, // 1句
};
/** followUp 问题最大长度 */