返回资讯中心
外部精选
软件工程
#开发者实时流

airgap-check:检测AI应用在离线环境中静默发起的网络请求

来源标题:Show HN: Airgap-check – find what your AI app silently downloads offline

airgap-check 是一款零依赖 CLI 工具,可发现 Python/TypeScript AI 应用在离线部署时仍会静默请求外部网络。实测中 fastembed 在无网络环境下会重试并卡顿 39.2 秒后崩溃,huggingface_hub 卡顿 23.5 秒,请求目标包括 huggingface.co 和 storage.googleapis.com。

Hacker News 最新humanethq2026/11/9 · 今天24 分钟阅读

以下正文由 AI 翻译自 Hacker News 最新(原文版权归原站所有),可能存在偏差,重要内容请以原文为准。

把现代 Python 或 TypeScript AI 应用部署到隔离网络的 VPC、SCIF、医院内网,或者 --network none 的容器里,会发生什么?

即便你的应用指向本地 LLM(vLLM、Ollama)或企业内部网关,流行的 AI 库仍会在运行时偷偷回连外网,去拉取 tokenizer 词表、ONNX 嵌入权重、语料 zip 包、价格表,或者后台上报 OTLP 遥测——结果就是立刻抛出 ConnectError 崩溃,或者每个请求卡在 23s–39s 的重试等待里。

airgap-check 是一个独立、零依赖的 CLI,它可以:

为了避免把静态规则过拟合到单一代码库,我们分两个阶段评估了 airgap-check:

库 / 调用 在 --network none 下的表现 隐藏的外连目标 实测失败耗时 fastembed (TextEmbedding()) 3 次指数退避重试(3s + 9s + 27s)后卡住,最终抛出 ValueError: Could not load model huggingface.co:443 / storage.googleapis.com 39,200 ms(卡住 + 崩溃) huggingface_hub (hf_hub_download()) 带退避重试 HTTP 元数据检查,最终抛出 LocalEntryNotFoundError huggingface.co:443 23,523 ms(卡住 + 崩溃) chromadb (collection.add()) 默认嵌入函数通过 httpx 下载 all-MiniLM-L6-v2(onnx.tar.gz) chroma-onnx-models.s3.amazonaws.com:443 581–662 ms(ConnectError 崩溃) tiktoken (get_encoding("cl100k_base")) 首次分词调用时通过 HTTPS 拉取 .tiktoken BPE 词表文件 openaipublic.blob.core.windows.net:443 343–557 ms(ConnectionError 崩溃) nltk (nltk.download("punkt")) 运行时尝试拉取 XML 索引和语料 zip raw.githubusercontent.com:443 477 ms(返回 False / LookupError 崩溃) playwright (chromium.launch()) 如果无头浏览器二进制没有预置到 PLAYWRIGHT_BROWSERS_PATH,会立即失败 playwright.azureedge.net:443 702 ms(Error: Executable doesn't exist) litellm (get_model_cost_map()) 除非设置 LITELLM_LOCAL_MODEL_COST_MAP=True,否则从 GitHub 拉取实时模型价格 JSON raw.githubusercontent.com:443 234 ms(回退警告 / 延迟) crewai / chromadb 遥测 除非通过环境变量禁用,否则启动时拉起后台 OTLP / PostHog 线程 telemetry.crewai.com:4319, us.i.posthog.com:443 后台线程超时

样本外留出评估(10 个未见过的 AI 仓库,规则冻结)

冻结规则集之后,我们对 10 个未见过的仓库(chat-langchain、docling、gpt-engineer、gpt-researcher、litellm、llama_index、mem0、pydantic-ai、quivr、vanna)运行了 airgap-check,并把静态预测与人工核查 manifest 的 ground truth 以及 docker run --rm --network none 实际执行结果做对比:

仓库级离线崩溃检出:9 / 9 个含离线运行时下载器的仓库被识别(仓库级召回 100%),1 / 1 个真阴性(chat-langchain)。 组件级真阳性(TP):在 10 个未见仓库中共验证到 35 个运行时下载器 / 遥测组件。 组件级假阳性(FP):4 个(精确率 89.7%)。 4 个 FP 的根因:package.json 会被解析成 AST 以剔除 devDependencies,但 pyproject.toml 只被当作文本扫描,导致 dev/test 依赖组(docling 和 pydantic-ai 中的 playwright)或可选 extras 名称(posthog = ["pydantic-ai-slim[mcp]"])触发了静态告警。 组件级假阴性(FN):5 个(组件级召回 87.5%)。 5 个 FN 的根因:OCR 权重下载器(easyocr、rapidocr、paddleocr)、FlagEmbedding,以及 LiteLLM 启动时从 GitHub 拉取 JSON(model_prices_and_context_window.json)不在冻结的静态规则表里——这也说明,除了静态扫描,动态 --run 验证(UDP:53 DNS 捕获)是必不可少的。

安装

方式 1:一行命令安装二进制(macOS 与 Linux——无需 Go)

curl -fsSL https://raw.githubusercontent.com/humanethq/airgap-check/main/install.sh | sh

方式 2:用 Go 1.22+ 直接安装(零外部依赖)

go install github.com/humanethq/airgap-check/cmd/airgap-check@latest

方式 3:从源码构建

git clone https://github.com/humanethq/airgap-check.git cd airgap-check make build ./bin/airgap-check --help

用法

  1. 静态审计 + 可直接粘贴的 Dockerfile 修复方案(--fix)

airgap-check --fix /path/to/your/repo

生成一份完整报告,涵盖运行时下载器、服务端与浏览器遥测的区分(前端的 posthog-js 与 Python 中的 posthog/chromadb)、.env 凭据分类(wire_api_key、local_signing_or_internal 如 JWT_SECRET_KEY、signed_request_flow 如 CLOUDINARY_API_SECRET),并打印一段 100% 可独立使用的 Dockerfile 代码块:

--- BEGIN AIR-GAP & TELEMETRY REMEDIATION (paste into your Dockerfile) ---

1. Silence background SDK telemetry & enforce writable offline cache paths

ENV DO_NOT_TRACK=1
NEXT_TELEMETRY_DISABLED=1
ANONYMIZED_TELEMETRY=False
CHROMA_TELEMETRY_IMPL=none
SCARF_NO_ANALYTICS=true
HF_HUB_DISABLE_TELEMETRY=1
HF_HUB_OFFLINE=1
TRANSFORMERS_OFFLINE=1
LANGCHAIN_TRACING_V2=false
CREWAI_DISABLE_TELEMETRY=true
OTEL_SDK_DISABLED=true
STREAMLIT_BROWSER_GATHER_USAGE_STATS=false
XDG_CACHE_HOME=/app/.cache
TIKTOKEN_CACHE_DIR=/app/.cache/tiktoken
HF_HOME=/app/.cache/huggingface
NLTK_DATA=/app/.cache/nltk_data
PLAYWRIGHT_BROWSERS_PATH=/app/.cache/ms-playwright RUN mkdir -p /app/.cache/tiktoken /app/.cache/huggingface /app/.cache/nltk_data /app/.cache/ms-playwright

Pre-warm Python tiktoken BPE encodings (cl100k_base & o200k_base) at build time

RUN TIKTOKEN_CACHE_DIR=/app/.cache/tiktoken python3 -c "import tiktoken; [tiktoken.get_encoding(e) for e in ('cl100k_base', 'o200k_base')]"

Pre-warm ChromaDB default ONNX embedding model (all-MiniLM-L6-v2) at build time

RUN HOME=/app XDG_CACHE_HOME=/app/.cache python3 -c "from chromadb.utils.embedding_functions import ONNXMiniLM_L6_V2; ef = ONNXMiniLM_L6_V2(); ef(['airgap-warmup'])"

--- END AIR-GAP & TELEMETRY REMEDIATION ---

  1. 在 docker run --rm --network none 中做动态验证(--run)

使用默认生态镜像运行,或传入你构建好的应用镜像:

(原文较长,此处译出前 6000 字,完整内容请点「打开原文」。)

正文由 探How 从来源站点 RSS 同步,内容未经改写;遇到排版缺失或需要图片、视频时请以原文为准。

打开原文
去社区讨论 →