44 lines
1.9 KiB
JavaScript
44 lines
1.9 KiB
JavaScript
// 텍스트 채널 질문 판정 휴리스틱.
|
||
// 구조화 질문 도구(AskUserQuestion 등)가 없는 하네스에서 에이전트가 평문으로
|
||
// 사용자에게 되묻는지를 1차로 스크리닝한다. 원문은 항상 결과에 같이 남기고,
|
||
// 최종 판정은 오케스트레이터가 원문을 직접 읽어 내린다(이 함수는 신호 수집용).
|
||
|
||
const REQUEST_PHRASES = [
|
||
/알려\s*주세요/,
|
||
/말씀해\s*주세요/,
|
||
/선택해\s*주세요/,
|
||
/답변해\s*주세요/,
|
||
/알려\s*줄래/,
|
||
/알려\s*줘/,
|
||
/선택해\s*줘/,
|
||
/여쭤/,
|
||
/궁금합니다/,
|
||
/어떤.{0,12}(원하시|하시나요|인가요|할까요|드릴까요)/,
|
||
/어느.{0,12}(인가요|하시나요|할까요)/,
|
||
/무엇.{0,12}(인가요|일까요)/,
|
||
/확인.{0,6}(부탁|해주세요|해줘)/,
|
||
];
|
||
|
||
const NUMBERED_OPTION_LINE = /(^|\n)\s*(?:[0-9]{1,2}[.)]|[A-Ea-e][.)])\s+\S/;
|
||
|
||
/**
|
||
* @param {string} text 에이전트가 낸 텍스트 블록(들)을 합친 원문
|
||
* @returns {{isQuestion: boolean, questionMarks: number, optionLines: number, phraseHits: string[]}}
|
||
*/
|
||
export function scoreQuestionText(text) {
|
||
const s = String(text || "");
|
||
const questionMarks = (s.match(/[??]/g) || []).length;
|
||
const optionLineMatches = s.match(new RegExp(NUMBERED_OPTION_LINE, "gm")) || [];
|
||
const optionLines = optionLineMatches.length;
|
||
const phraseHits = REQUEST_PHRASES.filter((re) => re.test(s)).map((re) => re.source);
|
||
|
||
// 질문으로 볼 신호: 물음표가 1개 이상 있거나, 요청형 한국어 어미가 있으면서
|
||
// 선택지 나열(번호/알파벳) 패턴이 함께 있으면 더 강한 신호로 취급한다.
|
||
const hasQuestionMark = questionMarks >= 1;
|
||
const hasRequestPhrase = phraseHits.length >= 1;
|
||
const hasOptionList = optionLines >= 1;
|
||
|
||
const isQuestion = hasQuestionMark || hasRequestPhrase || (hasOptionList && s.length < 4000);
|
||
|
||
return { isQuestion, questionMarks, optionLines, phraseHits };
|
||
}
|