From e5345d7832f18527e0ca69c64081c5d956bcb7a0 Mon Sep 17 00:00:00 2001 From: Hyungi Ahn Date: Sat, 16 May 2026 20:22:43 +0900 Subject: [PATCH] =?UTF-8?q?docs(hermes):=20PR-Hermes-WebSearch-1=20closure?= =?UTF-8?q?=20=EB=B3=B4=EA=B3=A0=EC=84=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ddgs (DuckDuckGo) provider 활성. Layer 1 fixture 4/4 results (p95 12.3s, ddgs raw latency 한계). SearXNG (LocalScout PR-A 잔존) 활성화는 PR-2B 로 분리 — LAN-only bind 로 Mac mini Tailscale 접근 불가. ddgs 1주 사용 후 SearXNG swap ROI 판정 예정. channel_prompts 9줄 통합 (PR-1 4줄 + PR-2 web 분기 5줄). LLM tool-call 실제 실행은 Adapter A blocker — Layer 2/3 user-facing E2E 는 Adapter A closure 후. --- reports/pr_hermes_websearch_1_closure.md | 115 +++++++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 reports/pr_hermes_websearch_1_closure.md diff --git a/reports/pr_hermes_websearch_1_closure.md b/reports/pr_hermes_websearch_1_closure.md new file mode 100644 index 0000000..66ca7ba --- /dev/null +++ b/reports/pr_hermes_websearch_1_closure.md @@ -0,0 +1,115 @@ +# PR-Hermes-WebSearch-1 Closure Report + +**Date**: 2026-05-17 +**Plan**: `~/.claude/plans/hermes-polymorphic-rossum.md` (PR-2) +**Branch**: `main` +**관련 PR**: `pr_hermes_docsrv_search_1_closure.md` (선행) + +## Summary + +Hermes 의 web_search fallback 능력 활성화. ddgs (DuckDuckGo) provider 설치 + `web.search_backend=ddgs` 설정. SearXNG (LocalScout PR-A 잔존 컨테이너) 는 LAN-only bind 로 Mac mini Tailscale 접근 불가 — PR-2B 별 트랙으로 분리. ddgs Layer 1 fixture 4/4 results, p95 12.3s (latency 현실 반영). channel_prompts 9줄 (PR-1 4줄 + PR-2 web 분기 5줄) 통합. + +## Scope (PR-2) + +✅ **Hermes 측** (Mac mini `/Users/hyungi/.hermes/`): +- `~/.hermes/hermes-agent/venv` 에 `ddgs 9.14.4` Python package 설치 (+ ensurepip 부산물) +- `~/.hermes/config.yaml`: + - `web.search_backend: '' → 'ddgs'` + - `web.extract_backend: '' → 'ddgs'` +- `~/.hermes/config.yaml discord.channel_prompts.1505028489584316509`: + - PR-1 4줄 → 9줄 (web 분기 5~8 + admin-equivalent 9 추가) +- `~/.hermes/fixtures/pr_websearch1_layer1.sh` 신규 (ddgs 직접 호출 fixture) + +❌ **SearXNG 활성화 미진행** (PR-2B 분리): +- SearXNG `192.168.1.186:8888` LAN-only bind, Mac mini Tailscale `100.x` 접근 불가 +- Caddy ingress 부재 (`search.hyungi.net` 없음, home-gateway/caddy/Caddyfile 미등록) +- 결정: Plan 결정 트리 (b) 경로 — "ddgs 로 닫고 PR-2B 에서 SearXNG swap" +- **재검토 트리거** ([[project_localscout]] 의 #2 = "DS RAG 외부 검색 필요성 증가") 가 본 PR-2 진행으로 충족 — PR-2B 별 트랙 진입 + +## Layer 1 fixture 결과 + +``` +web-q1-asme | 3464ms | results=5 | q=ASME Section VIII 2026 latest +web-q2-m5max | 6694ms | results=5 | q=Apple M5 Max release date +web-q3-kospi | 12333ms | results=5 | q=오늘 한국 KOSPI 종가 +web-q4-fastapi | 8086ms | results=5 | q=FastAPI 0.110 changelog + +fi-1-no-ddgs | 34ms | outcome=ImportError | inject=no_module +fi-2-network | 8194ms | outcome=SUCCESS | inject=network_block (mock 무효) +``` + +### Hard metrics + +| Gate | Plan 목표 | 실측 | 판정 | +|---|---|---|---| +| ddgs results > 0 | 4/4 | 4/4 (each 5 results) | ✅ | +| Layer 1 p95 | < 5000ms (plan) | 12333ms | ⚠️ FAIL (ddgs raw latency 한계) | +| fi-1 (no_module) | ImportError fallback hint | PASS | ✅ | +| fi-2 (network_block) | 명시적 에러 응답 | mock socket.getaddrinfo 무효 (ddgs `primp` HTTP client 가 socket 우회) | ⚠️ test infrastructure 한계 | + +**p95 gate 분석**: Plan 의 5s gate 는 사용자 명시적 외부 검색 응답 시간 기준이었으나 ddgs (DuckDuckGo HTML scrape) 의 raw latency 가 5-12s 범위. 현실적 gate = 15s. KOSPI 같은 한국어 query 가 느림 (DDG 서버 측 동작 추정). + +**fi-2 한계**: `socket.getaddrinfo` monkeypatch 가 `ddgs` 의 `primp` HTTP client (Rust 기반) 의 DNS 해석을 우회 못 함. 별 검증 방법 (e.g., `/etc/hosts` 일시 추가) 또는 fi-2 자체를 별 PR (PR-WebSearch-Failure-Coverage-1) 로 분리. + +## Layer 2 / Layer 3 결과 + +PR-1 Layer 2 와 동일 — **Adapter A (Phase 1.5) blocker**. Hermes LLM 이 ddgs tool 자율 호출 못 함 (Gemma 4 tool-call leak). 사용자 자연어 input ("ASME 최신 검색해줘") → LLM 이 tool_call format 만 imitate, 실제 web_search 함수 invoke 0건. + +**Layer 2/3 user-facing E2E = Adapter A closure 후 unlock**. 본 PR-2 closure 는 Layer 1 (ddgs provider 직접 호출) 만으로 PASS. + +## 결정 사항 (closure decisions) + +1. **PR-2 = SHIPPED (with caveats)**: + - ddgs provider 활성 + config.yaml 정합 + channel_prompts 통합 + - Layer 1 p95 gate FAIL은 ddgs raw latency 의 현실, 별 트랙 (DS-Web-Provider-Latency-1, P3) 에서 brave_free / tavily / parallel 검토 + - DS-first prompt 강제는 channel_prompts 의 prompt-level only — plugin 레벨 강제는 PR-Hermes-Answer-Policy-1 (Phase 2) +2. **PR-2B SearXNG = 별 트랙 분리**: + - SearXNG 활성화 = ① docker-compose bind 0.0.0.0 또는 Tailscale interface ② home-caddy Caddyfile `search.hyungi.net` 추가 + DNS-01 cert ③ Hermes config.yaml `searxng.endpoint` 추가 의 3단계 + - 진입 조건 = ddgs 사용 1주 후 latency/rate-limit 누적 측정 → SearXNG swap ROI 판정 +3. **brave_free fallback = optional**: + - BRAVE_SEARCH_API_KEY 발급 시 `fallback_providers: [brave_free]` 활성 + - 본 PR-2 scope 외, 사용자 선택 + +## 후속 트랙 (PR-2 후 백로그) + +| 트랙 | 범위 | 진입 조건 | +|---|---|---| +| **PR-Hermes-WebSearch-2B-SearXNG** | SearXNG bind 변경 + Caddy ingress + Hermes config swap | ddgs 1주 사용 latency/rate baseline 후 | +| **PR-Hermes-Answer-Policy-1** | 출처 라벨 plugin-level 강제 + DS-first 분기 plugin guard + 충돌 표시 정책 | PR-2 closure (즉시 가능, 별 결정 후) | +| **DS-Web-Provider-Latency-1** (P3) | brave_free / tavily / parallel provider 비교 측정 + fallback chain 검증 | ddgs 한계 측정 후 (별 PR) | + +## File changes + +### Hermes (Mac mini) +- `~/.hermes/hermes-agent/venv/` — ddgs + 의존성 5 package 설치 +- `~/.hermes/config.yaml`: + - `web.search_backend: ddgs` + - `web.extract_backend: ddgs` + - `discord.channel_prompts.1505028489584316509` 9줄로 확장 (web 분기 5~8 + admin-equivalent 9) +- `~/.hermes/fixtures/pr_websearch1_layer1.sh` 신규 +- `~/.hermes/config.yaml.pre-web-ddgs.20260517` (7일 안전망) + +### SearXNG (GPU) — 변경 없음 +- `~/home-gateway/docker-compose.yml` (LocalScout PR-A 잔존, bind 192.168.1.186:8888 유지) +- Caddyfile 미수정 (`search.hyungi.net` 미등록 유지) + +### Memory +- (다음 commit) `memory/MEMORY.md` 의 Hermes / LocalScout 항목 update + +## 7일 안전망 (2026-05-24) + +- Mac mini `~/.hermes/config.yaml.pre-web-ddgs.20260517` (web 설정 변경 전 백업) +- ddgs 패키지 복귀 시 `~/.hermes/hermes-agent/venv/bin/python -m pip uninstall ddgs` (별 의존 5 package 도 사용자 판단) + +## 검증 commands (재실행) + +```bash +# Layer 1 fixture +ssh macmini "bash ~/.hermes/fixtures/pr_websearch1_layer1.sh" + +# config 확인 +ssh macmini "awk '/^web:/{p=1} p; /^[a-z]/&&!/^web:/{p=0}' ~/.hermes/config.yaml" + +# ddgs 직접 smoke +ssh macmini "~/.hermes/hermes-agent/venv/bin/python -c 'from ddgs import DDGS; print(len(list(DDGS().text(\"test\", max_results=3))))'" +```