Commit ·
8e87d9c
1
Parent(s): 48b03a2
search: parse knowledgeGraph/peopleAlsoAsk; treat 0-result as ok+hint
Browse filesTwo robustness fixes for Serper search:
- Fold in knowledgeGraph (description + attributes) and peopleAlsoAsk
blocks. For many queries `organic` is empty but these carry the answer.
- When Serper genuinely returns nothing, return ok=True with an empty
result set + a "reformulate, drop quotes/rare acronyms" hint instead of
ok=False. Previously a 0-result Serper response was treated as a backend
failure, which fell through to the rate-limited DuckDuckGo path and
surfaced a misleading "all search backends failed" error. Now the agent
gets actionable feedback and the DDG 202 noise is gone. Mirrors
inference/tool_search.py "use a less specific query" behaviour.
app.py
CHANGED
|
@@ -1403,8 +1403,9 @@ def _serper_search(query: str, max_results: int) -> Dict[str, Any]:
|
|
| 1403 |
"body": item.get("snippet", ""),
|
| 1404 |
}
|
| 1405 |
)
|
| 1406 |
-
# Fold in the answer box
|
| 1407 |
-
#
|
|
|
|
| 1408 |
answer_box = data.get("answerBox") or {}
|
| 1409 |
if answer_box:
|
| 1410 |
rows.insert(
|
|
@@ -1417,13 +1418,50 @@ def _serper_search(query: str, max_results: int) -> Dict[str, Any]:
|
|
| 1417 |
or "",
|
| 1418 |
},
|
| 1419 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1420 |
if not rows:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1421 |
return {
|
| 1422 |
-
"ok":
|
| 1423 |
"query": query,
|
| 1424 |
-
"error": "Serper returned no organic results",
|
| 1425 |
"results": [],
|
|
|
|
| 1426 |
"backend": "serper",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1427 |
}
|
| 1428 |
return {
|
| 1429 |
"ok": True,
|
|
|
|
| 1403 |
"body": item.get("snippet", ""),
|
| 1404 |
}
|
| 1405 |
)
|
| 1406 |
+
# Fold in the answer box, knowledge graph and "people also ask" when
|
| 1407 |
+
# present; for many queries `organic` is empty but these rich blocks
|
| 1408 |
+
# still carry the exact fact the model is looking for.
|
| 1409 |
answer_box = data.get("answerBox") or {}
|
| 1410 |
if answer_box:
|
| 1411 |
rows.insert(
|
|
|
|
| 1418 |
or "",
|
| 1419 |
},
|
| 1420 |
)
|
| 1421 |
+
kg = data.get("knowledgeGraph") or {}
|
| 1422 |
+
if kg:
|
| 1423 |
+
kg_body = kg.get("description", "") or ""
|
| 1424 |
+
attrs = kg.get("attributes") or {}
|
| 1425 |
+
if attrs:
|
| 1426 |
+
kg_body = (kg_body + " " + "; ".join(
|
| 1427 |
+
f"{k}: {v}" for k, v in attrs.items()
|
| 1428 |
+
)).strip()
|
| 1429 |
+
if kg.get("title") or kg_body:
|
| 1430 |
+
rows.append(
|
| 1431 |
+
{
|
| 1432 |
+
"title": kg.get("title", "Knowledge graph"),
|
| 1433 |
+
"href": kg.get("descriptionLink") or kg.get("website", ""),
|
| 1434 |
+
"body": kg_body,
|
| 1435 |
+
}
|
| 1436 |
+
)
|
| 1437 |
+
for paa in (data.get("peopleAlsoAsk") or [])[:3]:
|
| 1438 |
+
if paa.get("question"):
|
| 1439 |
+
rows.append(
|
| 1440 |
+
{
|
| 1441 |
+
"title": paa.get("question", ""),
|
| 1442 |
+
"href": paa.get("link", ""),
|
| 1443 |
+
"body": paa.get("snippet", ""),
|
| 1444 |
+
}
|
| 1445 |
+
)
|
| 1446 |
if not rows:
|
| 1447 |
+
# Serper worked but the query genuinely matched nothing. Return a
|
| 1448 |
+
# SUCCESSFUL-but-empty result (ok=True) carrying an actionable hint,
|
| 1449 |
+
# rather than ok=False — that way the agent is told to reformulate
|
| 1450 |
+
# instead of seeing a scary "all backends failed" message, and we
|
| 1451 |
+
# skip the rate-limited DuckDuckGo fallback (which would also find
|
| 1452 |
+
# nothing). Mirrors inference/tool_search.py's "use a less specific
|
| 1453 |
+
# query" behaviour.
|
| 1454 |
return {
|
| 1455 |
+
"ok": True,
|
| 1456 |
"query": query,
|
|
|
|
| 1457 |
"results": [],
|
| 1458 |
+
"cached": False,
|
| 1459 |
"backend": "serper",
|
| 1460 |
+
"note": (
|
| 1461 |
+
"No results for this query. Reformulate and search again: "
|
| 1462 |
+
"remove quotation marks (they force exact-phrase matching), "
|
| 1463 |
+
"drop rare acronyms, and use fewer / more common keywords."
|
| 1464 |
+
),
|
| 1465 |
}
|
| 1466 |
return {
|
| 1467 |
"ok": True,
|