fix(ai写作): 技能检索超时硬编码 5 分钟(内网慢检索不被过早切断)

内网检索很慢,原 120s 在三个真正生效的层把检索切断。统一硬编码 300s,
不依赖环境变量(部署方不一定会配):
- researcher._SKILL_SEARCH_TIMEOUT_SECONDS:120(env) → 300(写死),删掉 _env_int;
  作用于直连/定向技能检索的 wait_for,也传给真实智能体路径。
- IntranetSearchProvider 默认 httpx 超时:120 → 300(直连内网 ES 的真正瓶颈)。
- run_skill_via_real_agent 整段运行上限:max(timeout_s, 300),至少 5 分钟。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
fengxiangdebaoziandClaude Opus 4.8 committed 2026-06-24 22:54:42 +08:00
1 parent 4f68235c94
commit d8b43e7579
3 files changed
+13 -16

No files matched your search

@@ -52,6 +52,11 @@ def use_skill_search_agent() -> bool:
# 单次工具调用循环上限(防跑飞)。
_REAL_AGENT_MAX_TURNS = 16
# 真实智能体跑技能:整段运行(读 SKILL.md + 多轮工具调用)的超时上限,**硬编码 5 分钟**。
# 内网检索很慢、技能常做多次检索,单次直连检索的 120s 不够整段用;这里写死,不依赖 env
# (部署方不一定会配环境变量),保证内网慢检索至少有 5 分钟才被切断。
_REAL_AGENT_TIMEOUT_SECONDS = 300
_MATERIAL_OUTPUT_CONTRACT = (
"你的任务:严格按上面挂载的检索技能(SKILL.md)的说明,用相应工具检索与「写作意图」相关的**真实素材**。\n"
"- 必须按技能说明实际调用工具完成检索(读取知识库文件 / 调用内网检索接口 / MCP 等),**不得凭记忆编造**。\n"
@@ -128,7 +133,9 @@ async def run_skill_via_real_agent(
skills=[skill_name], # 仅加载这个技能的 SKILL.md
model=model_name or "inherit",
max_turns=_REAL_AGENT_MAX_TURNS,
timeout_seconds=max(30, timeout_s),
# 整段运行硬编码至少 5 分钟(_REAL_AGENT_TIMEOUT_SECONDS),内网慢检索不被过早切断;
# 调用方传入更大的 timeout_s 时以更大者为准。
timeout_seconds=max(timeout_s, _REAL_AGENT_TIMEOUT_SECONDS),
)
thread_id = (config.get("configurable") or {}).get("thread_id")
@@ -86,19 +86,9 @@ _MAX_KEYWORD_COUNT = 10
# 单个技能的检索超时(秒)。技能检索是顺序循环,provider 偶发限速/挂起会把整段
# "技能检索过程"拖住;超时即放弃该技能、emit 0 条结果继续下一个,保证时间线持续推进。
# 默认 120s(≥2 分钟):内网检索 provider 本身就允许 timeout=120,之前 25s 会过早放弃
# 慢但有效的检索。可用环境变量 AI_WRITING_SKILL_SEARCH_TIMEOUT_SECONDS 覆盖。
def _env_int(name: str, default: int) -> int:
raw = (os.getenv(name) or "").strip()
if raw:
try:
return max(1, int(raw))
except ValueError:
pass
return default
_SKILL_SEARCH_TIMEOUT_SECONDS = _env_int("AI_WRITING_SKILL_SEARCH_TIMEOUT_SECONDS", 120)
# **硬编码 300s(5 分钟)**:内网检索很慢,给足时间不被过早切断;不依赖环境变量
# (部署方不一定会配),需要更长时改这里即可。
_SKILL_SEARCH_TIMEOUT_SECONDS = 300
# 内置「知识库检索」技能名:素材收集专家 agent 的默认技能。researcher 对它
# 特殊处理——不用 description 拼 query,而是对 Step 1 生成的全部检索词做
@@ -27,12 +27,12 @@ class IntranetSearchProvider(BaseSearchProvider):
self,
base_url: str = "",
knowledge_base_name: str = _DEFAULT_KB,
timeout: int = 120,
timeout: int = 300,
**_ignored,
):
self.endpoint = base_url or _DEFAULT_ENDPOINT
self.knowledge_base_name = knowledge_base_name or _DEFAULT_KB
# 内网 ES 接口可能较慢,超时放宽到 2 分钟
# 内网 ES 接口很慢,超时硬编码放宽到 5 分钟(不依赖 env 配置)
self.timeout = timeout
# 收集本次运行的检索异常,供 researcher 节点取出并提示用户(ES 波动等)
self.errors: list[str] = []