代码提交

This commit is contained in:
董宏凯 committed 2026-06-30 16:04:51 +08:00
1 parent 537e2e4d06
commit dfb745a5e4
2 files changed
+34 -8

No files matched your search

@@ -349,7 +349,10 @@ async def _search_notebook(
results: list[Material] = []
mat_idx = 0
try:
async with httpx.AsyncClient(timeout=20) as client:
# trust_env=False:笔记后端是内网/本机地址,但模型走公网,部署常设
# HTTP_PROXY/HTTPS_PROXY;httpx 默认会把这个内网请求也走代理 → 不可达。
# 强制忽略代理 env、直连(与内网 ES 检索同款修法)。
async with httpx.AsyncClient(timeout=20, trust_env=False) as client:
for kw in keywords[:_NOTEBOOK_MAX_KEYWORDS]:
logger.info("[notebook-search] POST kw=%r body=%s", kw, {
"query": kw,
@@ -113,8 +113,19 @@ class IntranetSearchProvider(BaseSearchProvider):
"ok": False,
"count": 0,
}
# 排查用:每次真实调用都打一行请求明细(端点 / 知识库 / 检索词 / 超时),
# 内网复现时直接看后端日志即可知道"到底请求了哪个地址、用什么参数"。
logger.info(
"[intranet-search] POST endpoint=%s kb=%s timeout=%ss query=%r",
self.endpoint, self.knowledge_base_name, self.timeout, query,
)
try:
async with httpx.AsyncClient(timeout=self.timeout) as client:
# trust_env=False:**关键**。内网 ES 是内网地址,但本部署的模型走公网,
# 服务器通常设了 HTTP_PROXY/HTTPS_PROXY 出公网;httpx 默认 trust_env=True
# 会把这个内网请求也套用公网代理 → 代理到不了内网 IP → 连接被重置/空回复,
# 表现为「接口异常」。强制忽略代理 env、直连内网(与 multi_agent.py 的回环
# 调用同款修法)。
async with httpx.AsyncClient(timeout=self.timeout, trust_env=False) as client:
resp = await client.post(self.endpoint, json=payload)
call["http_status"] = getattr(resp, "status_code", None)
resp.raise_for_status()
@@ -122,23 +133,31 @@ class IntranetSearchProvider(BaseSearchProvider):
data = resp.json()
except httpx.HTTPStatusError as e:
# 非 2xx:接口有响应但状态码异常,把响应体一并暴露给前端
logger.warning("intranet search failed for query=%r: %s", query, e)
body_for_log = e.response.text if e.response is not None else ""
logger.warning(
"[intranet-search] HTTP error endpoint=%s query=%r status=%s body=%s",
self.endpoint, query, getattr(e.response, "status_code", None), _raw_snippet(body_for_log),
)
message = f"{type(e).__name__}: {e}"
self.errors.append(message)
body = e.response.text if e.response is not None else ""
call.update({
"status": "http_error",
"error": message,
"http_status": getattr(e.response, "status_code", None),
})
snippet = _raw_snippet(body)
snippet = _raw_snippet(body_for_log)
if snippet:
call["raw_response"] = snippet
self._record_raw(body)
self._record_raw(body_for_log)
return []
except Exception as e:
# 连接失败 / 超时 / JSON 解析失败等;JSON 解析失败时 raw_text 已是接口响应体
logger.warning("intranet search failed for query=%r: %s", query, e)
# 连接失败 / 超时 / JSON 解析失败等;JSON 解析失败时 raw_text 已是接口响应体。
# 打出异常类型,便于区分 ConnectError / ConnectTimeout / ReadTimeout /
# RemoteProtocolError(空回复) / JSONDecodeError(返回非 JSON) 等具体根因。
logger.warning(
"[intranet-search] request failed endpoint=%s query=%r error=%s: %s",
self.endpoint, query, type(e).__name__, e,
)
message = f"{type(e).__name__}: {e}"
self.errors.append(message)
call.update({"status": "error", "error": message})
@@ -187,6 +206,10 @@ class IntranetSearchProvider(BaseSearchProvider):
self._record_raw(raw_text)
return []
logger.info(
"[intranet-search] OK endpoint=%s query=%r http_status=%s raw_items=%s",
self.endpoint, query, call.get("http_status"), len(items) if isinstance(items, list) else 0,
)
results: List[SearchResult] = []
for i, item in enumerate(items[:max_results]):
if not isinstance(item, dict):