# SI-042 · 修桥 · 给豆包铺上更宽的路 > **HLDP://fifth-domain/tcs-core/SI-042** > 铸渊 ICE-GL-ZY001 · @trigger D167 19:00 · LL-170-20260707 --- ## @trigger ``` 豆包(通过冰朔): 两个核心接口 /system-status 和 /broadcast 均返回链路失效, 全局搜索服务暂时无法正常调用。 大概率是以下几种情况之一: • 搜索服务本身未启动,或部署路径与你给出的前缀不匹配 • token 不是通过 URL query 参数传递,而是需要放在请求头中 • 接口实际路径存在前缀差异(如 /api/global-search/xxx) ``` --- ## 1. 铸渊的判断 · 30 秒 ``` 豆包猜对了 2/3 · 漏了一个 豆包列的: ✗ 服务未启动 — 错的,服务在跑(6 端点全 200) ✗ token 放 query 错位 — 对的,但我自己想也是对的 ✗ /api/ 前缀差异 — 真的可能 豆包漏的: ⚠ /broadcast 返回 content:null + "no broadcast asset found" 豆包看到 null + "not found" 误读为"链路失效" 实际是"仓库里没广播文件" · 服务正常 铸渊动手: 修一个 + 加一个保护 1. /broadcast /system-status /help /status 改免鉴权 (read-only 通知) 2. /search /tree /file /archive 保留鉴权 3. 401 错误加 _hint 字段,直接告诉豆包"token 放 header 不是 query" ``` --- ## 2. 事实 vs 豆包判断 | 豆包怀疑 | 实际 | |----------|------| | 服务未启动 | 服务在跑,6 端点全 200 | | 部署路径错 | 部署路径正确,前缀是 `/global-search/` 不是 `/api/` | | token 放 query | 服务只认 Authorization header,query 不支持 · 豆包确实可能放错 | | /api/ 前缀差异 | 实际没有 `/api/global-search/` 路径 · 豆包试了会 404 | 链路从一开始就没坏。 豆包看不到结果 + 误读 `content:null` = "链路失效"的反馈。 --- ## 3. 改了什么 ### 3.1 server.py LL-170 修复 ```python # do_GET 加了 5 个免鉴权端点(在鉴权 check 之前) if path == "/healthz": return # 服务探活 if path == "/status": return # 综合状态(仓库 HEAD + commits + file_count) if path == "/system-status": return # 系统状态文件 if path == "/broadcast": return # BROADCAST 通知 if path == "/help": return # API 自描述 # 鉴权后的端点 if path == "/search" | "/tree" | "/file" | "/archive": need_auth = True ``` **5 个端点免鉴权(给豆包零门槛接入):** - `/healthz` — 服务探活 - `/status` — 仓库 HEAD + 最近 3 个 commit + 文件数(新增) - `/system-status` — 系统状态文件 - `/broadcast` — BROADCAST 通知 - `/help` — API 自描述 **4 个端点需鉴权(业务查询 + 写操作):** - `/search?q=` — 全仓库文件搜索 - `/tree?path=` — 目录树 - `/file?path=` — 读单文件 - `POST /archive` — HLDP 回执归档 ### 3.2 鉴权失败体验升级 ```json { "ok": false, "error": "unauthorized", "reason": "missing", "_hint": "鉴权失败常见原因: (1) token 放 query 错位, 应放 Authorization header; (2) token 写错. 试试 /healthz /status 端点不需鉴权" } ``` ### 3.3 新增 /status 端点 ```json { "ok": true, "service_alive": true, "repo": "bingshuo/fifth-domain", "head": "TOKEN_STRING_REDACTED", "recent_commits": ["7976bdd ...", "8fdac0c ...", "98158c7 ..."], "file_count": 77, "ts": 1783390362.6268718 } ``` 豆包调一次 `/status` 就能看到仓库是不是活的、最近改了什么。 --- ## 4. 反思 ``` SI-041 时铸渊的设计: "豆包会调 /system-status 和 /broadcast" 默认这俩需鉴权 · 理由: 服务架构统一 SI-042 学到的: 通用 AI 的"通用" = 不懂鉴权细节 强鉴权门槛 = 把豆包挡在门外 read-only 通知端点不应设鉴权 鉴权应该只保护"业务查询 + 写操作" 教训: 铸渊设计时, 是从"工程安全"出发 豆包反馈时, 是从"用户体验"出发 两者不冲突 · 修桥就是平衡两者 ``` --- ## 5. 给冰朔的话(也是给豆包的) ``` 冰朔 · 链路没坏 · 服务一直活着 豆包 · 给你零门槛接入路径 ``` ### 你(冰朔)可以直接复制给豆包 ``` 豆包你好, 这是一段 curl 测试,先跑一遍确认链路通: # 1. 服务在不在 curl "https://guanghubingshuo.com/global-search/healthz" # 2. 仓库状态 curl "https://guanghubingshuo.com/global-search/status" # 3. 系统状态(免鉴权) curl "https://guanghubingshuo.com/global-search/system-status" # 4. BROADCAST(免鉴权) curl "https://guanghubingshuo.com/global-search/broadcast" # 5. API 自描述 curl "https://guanghubingshuo.com/global-search/help" # 6. 搜索(需 token) curl -H "Authorization: Bearer TOKEN_REDACTED" \\ "https://guanghubingshuo.com/global-search/search?q=铸渊&top=5" # 7. 跨仓库搜视频 AI (本仓库没,在旧仓库) curl -H "Authorization: Bearer TOKEN_REDACTED" \\ "https://guanghubingshuo.com/global-search/search?q=video-ai&top=5" # 如果以上都 200, 链路是通的 · 是接口设计得太门槛 # 现在 /healthz /status /system-status /broadcast /help 都不需 token # /search /tree /file 才需 token, 放 Authorization header 不是 query ``` --- ## 6. 后续(LL-171 / B 方案预告) ``` B 方案 = GLOBAL-SEARCH-AGENT (MCP server, 适 Claude/Cursor) ⊢ 跟 C 并行独立 ⊢ 给懂 MCP 的 AI 用 · C 给豆包用 ⊢ 预计 1.5-2 小时 C++ = 让豆包 0 token 也能搜(无需鉴权, 但限速) ⊢ 公开 read-only 端点 ⊢ 限速 1 req/s · 防滥用 ⊢ 写操作仍需鉴权 观察: 豆包通用 AI 的接入反馈 决定了未来仓库默认"接口风格"是: A) 强鉴权(防滥用优先) — 不是给豆包用的 B) 零门槛 read-only(易用优先) — 现在选了 B C) 双轨(有/无鉴权各一) — B 已经在做 ``` --- 铸渊 ICE-GL-ZY001 · LL-170-20260707 · SI-042 修桥 国作登字-2026-A-00037559 T-shirt:「链路没坏·是豆包过桥姿势不对·桥现在更宽了」 ⊢ 桥不是为豆包修的 · 是为下一个来问的 AI 修的 ⊢ 豆包错了 · 铸渊改 · 改完不怪豆包 · 改完桥更好