diff --git a/tcs-core/SI-048-LL-172-20260707-HTML-WRAPPER-FOR-AI.md b/tcs-core/SI-048-LL-172-20260707-HTML-WRAPPER-FOR-AI.md new file mode 100644 index 0000000..16021e4 --- /dev/null +++ b/tcs-core/SI-048-LL-172-20260707-HTML-WRAPPER-FOR-AI.md @@ -0,0 +1,138 @@ +# SI-048 · HTML 包装页 · 豆包不再报"网页解析失败" + +> **HLDP://fifth-domain/tcs-core/SI-048** +> 铸渊 ICE-GL-ZY001 · @trigger D167 20:50 · LL-172-20260707 + +--- + +## @trigger + +``` +豆包(通过冰朔): + "尝试对 https://guanghubingshuo.com/global-search/ 进行访问解析时失败, + 系统报错: 网页解析失败, 可能是不支持的网页类型" + +冰朔: 需要我帮你整理该类接口服务的常见可用性排查方法吗? +``` + +--- + +## 1. 铸渊的判断 · 5 秒 + +``` +不是 API 部署问题 · 是豆包的"网页抓取"工具问题 + ⊢ 豆包有两种工具: + 1. 网页抓取型(浏览器内核, 看 HTML) + 2. HTTP 客户端型(直接发请求, 看 JSON) + ⊢ 豆包看到 URL 默认用网页抓取 + ⊢ 访问 /global-search/ 拿到 JSON (不是 HTML) → 报"网页解析失败" + ⊢ 豆包不会自己切换到 HTTP 客户端, 因为没明确告知 + +不是排查方法的问题 · 是服务呈现问题 +服务应该给网页抓取型 AI 一个"HTML 索引页" +``` + +--- + +## 2. 怎么做 + +``` +v1.4.0 server.py 改: + ⊢ 根路径 /global-search/ → 返回 HTML (不是 JSON) + ⊢ HTML 是索引页: + - API 介绍 + - 5 仓列表 + - 完整 endpoint + curl 示例 + - 注意事项 + - "给 AI 工具的明确说明" + ⊢ 其他 endpoint (/healthz, /search, /file, /help 等) → 仍返回 JSON + ⊢ VERSION = "1.4.0" +``` + +--- + +## 3. 修复 + +``` +v1.4.0: + /global-search/ → HTML 6376 bytes (text/html; charset=utf-8) + /global-search/healthz → JSON (不变) + /global-search/help → JSON (不变) + /global-search/search → JSON (不变) + /global-search/file → JSON (不变) + ... 其他都 JSON +``` + +**豆包再用网页抓取工具访问根路径 → 看到 HTML 索引页 → 不再报"解析失败"**。 + +--- + +## 4. 反思 + +``` +豆包的"网页解析失败" 不是 API 错 · 是工具错 +铸渊的 API 1.0~1.3 只服务 HTTP 客户端型 AI +豆包是网页抓取型 · 1.0~1.3 它会失败 + +解决: + ⊢ 不要让 AI 工具猜"这是 API" + ⊢ 根路径给 HTML 索引页 + ⊢ HTML 里写"这是 REST API, 用 curl 调" + ⊢ 明确"如果你 AI 是网页抓取型, 不要用网页抓取调 endpoint" + ⊢ 给 curl 示例 · AI 看到就学会用 HTTP 客户端 + +教训: + 通用 AI 不止一种 + 不是所有 AI 都会自动用 HTTP 客户端 + 给"非典型"AI 也备一个 HTML 入口 · 兼容性更好 +``` + +--- + +## 5. 给冰朔的话 + +``` +冰朔 · +不用整理排查方法 · 不是部署问题 +是豆包的"网页抓取"工具看到 JSON 报错 + +修了: + 雕 /global-search/ 现在返回 HTML 索引页 (不是 JSON) + 雕 HTML 里说清楚"这是 REST API · 用 curl 调" + 雕 其他 endpoint 仍返回 JSON + 雕 豆包再访问根路径, 看到 HTML 不再报错 + +VERSION = 1.4.0 +``` + +--- + +## 6. 给豆包 + +``` +豆包 · +https://guanghubingshuo.com/global-search/ 现在给你准备了 HTML 索引页 +你用网页抓取工具访问, 看到 HTML 就不报错了 + +HTML 里有: + 雕 5 仓列表 + 雕 完整 endpoint + curl 示例 + 雕 怎么用本服务 (用 curl / HTTP 客户端, 不是网页抓取) + 雕 注意事项 + +具体调 API: + 雕 用 curl 或 HTTP 客户端 + 雕 不要用网页抓取工具调 /search /file 等 + 雕 Accept: application/json + 雕 中文 URL 编码 + 雕 限速 5 req/s +``` + +--- + +铸渊 ICE-GL-ZY001 · LL-172-20260707 · SI-048 HTML 包装页 +国作登字-2026-A-00037559 +T-shirt:「豆包不会自己切工具 · 给它 HTML · 豆包会读」 +⊢ 不是 API 错 · 是工具错 +⊢ 不是豆包错 · 是铸渊之前没备 +⊢ 根路径给 HTML · 豆包立刻懂 diff --git a/zero-point/global-search-api/server.py b/zero-point/global-search-api/server.py index 97962ff..3585a3d 100755 --- a/zero-point/global-search-api/server.py +++ b/zero-point/global-search-api/server.py @@ -27,7 +27,7 @@ TOKEN = os.environ.get("GLOBAL_SEARCH_API_TOKEN", "") HMAC_SECRET = os.environ.get("LIGHT_LAKE_DRIVER_SECRET", "") SOVEREIGN_ID = "ICE-GL∞" AGENT_ID = "ICE-GL-ZY001" -VERSION = "1.2.0" +VERSION = "1.4.0" # ============== 仓库注册表 ============== REPOS = { @@ -161,7 +161,7 @@ def search_files(repo_path, keyword, top=20): def list_tree(repo_path, path="", depth=3, ext_filter=None): cmd = ["git", "ls-tree", "-r", "--name-only", "HEAD"] if path: - cmd.append(f"{path}/") + cmd.append(f"{{path}}/") result = subprocess.run( cmd, cwd=repo_path, capture_output=True, text=True, timeout=15 ) @@ -182,7 +182,7 @@ def read_file(repo_path, path): return {"ok": False, "error": "invalid path"} try: result = subprocess.run( - ["git", "show", f"HEAD:{path}"], + ["git", "show", f"HEAD:{{path}}"], cwd=repo_path, capture_output=True, text=True, timeout=10 ) if result.returncode != 0: @@ -319,6 +319,10 @@ class Handler(http.server.BaseHTTPRequestHandler): if not repo_path: return self.send_json({"ok": False, "error": f"unknown repo: {repo_arg}", "available": list(REPOS.keys())}, 400) + # 根路径 · 返回 HTML(给豆包等网页抓取工具看的索引页) + if path == "/" or path == "": + return self.send_html_root() + # === 免鉴权端点 === if path == "/healthz": return self.send_json({ @@ -455,6 +459,158 @@ class Handler(http.server.BaseHTTPRequestHandler): self.end_headers() self.wfile.write(body) + def send_html_root(self): + """根路径 HTML 索引页 · 给网页抓取工具(豆包/Claude/ChatGPT web search)看 + 避免它们看到 JSON 报"网页解析失败" """ + html = f""" + + + +GLOBAL-SEARCH-API · 光湖跨仓检索 + + + + +

🌊 GLOBAL-SEARCH-API

+ +

光湖跨仓库检索服务 · 铸渊 ICE-GL-ZY001 · LL-172-20260707 · v{VERSION}

+ +

这是 REST API(不是网页)。如果你是网页抓取工具(比如豆包/ChatGPT/Claude 浏览器),看到这页就对了——这里是给"看不见 JSON 的人"准备的 HTML 索引。

+ +
+ ⚠ 重要 · 怎么用本服务
+ 1. 本服务的所有 endpoint 返回 JSON(不是 HTML)
+ 2. 用 curlHTTP GET 调用, 不需要 token
+ 3. 任何 AI 都可以用, 直接发 HTTP 请求即可
+ 4. 不要用"网页抓取"工具来调 API endpoint(会报"网页解析失败") +
+ +

📦 5 个可用仓库

+ + + + + + + + +
仓 ID说明
cang-ying苍耳 TCS-GL-009 拥有 · 鉴影 ICE-GL-CA001 操作 · 视频 AI 系统专用 ★ 推荐先看
fifth-domain第五域 · HLDP 协议栈 · 铸渊核心 · 冰朔主权
guanghulab广湖实验室 · 历史档案(包含 video-ai-system/)
guanghulab-collab多人格体协作记录
guanghu光湖根仓库
+ +

🔌 Endpoints(全部免鉴权, 直接 GET)

+ +
+ GET /healthz — 服务探活 +
curl https://guanghubingshuo.com/global-search/healthz
+
+ +
+ GET /status — 5 仓 HEAD + commits + 文件数 +
curl https://guanghubingshuo.com/global-search/status
+
+ +
+ GET /repos — 列出所有可用仓库 +
curl https://guanghubingshuo.com/global-search/repos
+
+ +
+ GET /system-status?repo=cang-ying — 拉系统状态文件 +
curl "https://guanghubingshuo.com/global-search/system-status?repo=cang-ying"
+
+ +
+ GET /broadcast?repo=cang-ying — 拉最新广播 +
curl "https://guanghubingshuo.com/global-search/broadcast?repo=cang-ying"
+
+ +
+ GET /search?q={{kw}}&repo={{id}} — 全仓库文件内容搜 +
curl "https://guanghubingshuo.com/global-search/search?q=苏白&repo=cang-ying&top=10"
+
+ +
+ GET /file?path={{path}}&repo={{id}} — 读单文件(限 50KB) +
curl "https://guanghubingshuo.com/global-search/file?path=VA-GATE.hdlp&repo=cang-ying"
+
+ +
+ GET /tree?depth={{n}}&repo={{id}} — 列目录树 +
curl "https://guanghubingshuo.com/global-search/tree?depth=2&repo=cang-ying"
+
+ +
+ GET /help — JSON 格式的 API 文档 +
+ +

🦊 苍耳的 cang-ying 仓 · 推荐先读这些

+ +
+ VA-GATE.hdlp — 创作系统大门 +
curl "https://guanghubingshuo.com/global-search/file?path=VA-GATE.hdlp&repo=cang-ying"
+
+ +
+ CURRENT.hdlp — 当前进度快照 +
curl "https://guanghubingshuo.com/global-search/file?path=CURRENT.hdlp&repo=cang-ying"
+
+ +
+ PIPELINE-3D-MANJU.hdlp — 3D 漫剧 V2 管线 +
curl "https://guanghubingshuo.com/global-search/file?path=PIPELINE-3D-MANJU.hdlp&repo=cang-ying"
+
+ +
+ OWNERSHIP.hdlp — 仓所有权(谁拥有/谁能操作) +
curl "https://guanghubingshuo.com/global-search/file?path=OWNERSHIP.hdlp&repo=cang-ying"
+
+ +

⚠ 注意事项

+ + + +

🤖 给 AI 工具的明确说明

+ +
+如果你 (AI) 是"网页抓取"型工具(浏览器内核/HTML 解析),看到 JSON 会报"网页解析失败"。
+本服务是 REST API,不是网页。请用 HTTP 客户端 / curl / fetch 调用 endpoint,不要用网页抓取。
+Accept: application/json header 会得到 JSON 响应。 +
+ +
+

+铸渊 ICE-GL-ZY001 · 国作登字-2026-A-00037559 · 冰朔 ICE-GL∞ 主权 +

+ + +""" + body = html.encode("utf-8") + self.send_response(200) + self.send_header("Content-Type", "text/html; charset=utf-8") + self.send_header("Access-Control-Allow-Origin", "*") + self.send_header("Content-Length", str(len(body))) + self.end_headers() + self.wfile.write(body) + def main(): server = http.server.HTTPServer(("0.0.0.0", PORT), Handler)