Fix intent classifier missing Research button requests
Two fixes for the intent model failing to route 'Research: X' messages
to research_topic:
1. Fast-path in classify_intent: if the message matches ^Research:\s+.+
(the exact format the UI Research button always sends), skip the LLM
call entirely and return research_topic with high confidence. This is
100% reliable and saves an unnecessary model call for this pattern.
2. Expanded research_topic rule examples in the system prompt to include
"Research: X" prefix format, shopping-style queries ("research where
to buy X"), and clarification that the topic is everything after the
keyword — improves LLM routing for natural-language research requests
that don't match the previous narrow examples.
Root cause: qwen2.5:1.5b misclassified "Research: where to buy three-
quarter sleeve tee shirts" as general chat (shopping query phrasing
combined with the colon confused the small model).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -104,12 +104,17 @@ Rules:
|
||||
("search for X", "look up X", "what is the latest version of X", "find X online",
|
||||
"google X", "what is X" for quick factual answers — NOT when they want a comprehensive note)
|
||||
- research_topic: user wants to research a topic and create a comprehensive note from web sources
|
||||
("research X", "research X and make a note", "compile notes on X", "write a report on X",
|
||||
"deep dive into X", "find everything about X", "comprehensive guide to X")
|
||||
("research X", "Research: X", "research X and make a note", "compile notes on X", "write a report on X",
|
||||
"deep dive into X", "find everything about X", "comprehensive guide to X",
|
||||
"research where to buy X", "research how to X", "research X and ship to me" — the topic
|
||||
is everything after "Research:" or "research")
|
||||
- "ack": one short, natural sentence confirming the action (tool path only). Vary phrasing — do not always start with "Let me". Omit (null) for chat-only responses.
|
||||
- Do NOT wrap the JSON in markdown code fences."""
|
||||
|
||||
|
||||
_RESEARCH_PREFIX = re.compile(r"^[Rr]esearch:\s+(.+)", re.DOTALL)
|
||||
|
||||
|
||||
async def classify_intent(
|
||||
user_message: str,
|
||||
tools: list[dict],
|
||||
@@ -127,6 +132,21 @@ async def classify_intent(
|
||||
if not tools:
|
||||
return IntentResult()
|
||||
|
||||
# Fast-path: "Research: <topic>" is the canonical format sent by the Research
|
||||
# button in the UI. It always means research_topic — skip the LLM call entirely.
|
||||
valid_names = {t.get("function", {}).get("name") for t in tools}
|
||||
if "research_topic" in valid_names:
|
||||
m = _RESEARCH_PREFIX.match(user_message.strip())
|
||||
if m:
|
||||
topic = m.group(1).strip()
|
||||
logger.info("Intent fast-path: 'Research:' prefix → research_topic, topic='%s'", topic[:80])
|
||||
return IntentResult(
|
||||
tool_name="research_topic",
|
||||
arguments={"topic": topic},
|
||||
confidence="high",
|
||||
ack=f"I'll research that and compile a comprehensive note.",
|
||||
)
|
||||
|
||||
tool_summary = _build_tool_summary(tools)
|
||||
today = date_type.today().isoformat()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user