{"repo": "antins-labs/searchos", "files": {"docs/providers.md": {"31d9e4248f0256347f208a67346a0e7931553e81": {"t": 1785674219.349758, "n": 10286, "h": "bcde75e6c5b5756a", "c": "# Model Provider Configuration\n\n**English** | [简体中文](zh/providers.md)\n\nSearchOS constructs its 11 model roles—such as `orchestrator`, `extraction`,\nand `judge`—through `searchos/config/models.py:get_model_for(role)`, backed by\nLangChain's `ChatOpenAI` and `ChatAnthropic` clients.\n\n**The fastest setup path is the interactive wizard.** The first\n`python -m searchos` run opens it automatically, or you can rerun it at any time\nwith `python -m searchos --setup`. For a manual setup, two environment variables\nare enough:\n\n```bash\n# .env (see .env.example in the repository root)\nSF_PROVIDER=zhipu-coding\nZHIPU_API_KEY=xxx\n```\n\n`SF_PROVIDER` generates default bindings for every role across five profiles:\n`main`, `judge`, `fast`, `synthesis`, and `reformat`. Advanced users can\noverride individual values with `SF_PROFILES__*` and `SF_ROLES__*`; these values\nare recursively merged without discarding other preset fields.\n\n## Preset overview\n\n### Coding plans using the Anthropic protocol\n\nThese vendor plans expose Anthropic-compatible endpoints originally intended\nfor coding clients. SearchOS connects through `ChatAnthropic` with a custom\n`base_url`.\n\n| `SF_PROVIDER` | Vendor | Endpoint | Key environment variable | Default models |\n|---|---|---|---|---|\n| `zhipu-coding` | Zhipu GLM Coding Plan (China) | `open.bigmodel.cn/api/anthropic` | `ZHIPU_API_KEY` | glm-5.2 / glm-4.7 |\n| `zai-coding` | Z.ai GLM Coding Plan (international) | `api.z.ai/api/anthropic` | `ZAI_API_KEY` | glm-5.2 / glm-4.7 |\n| `kimi-coding` | Kimi For Coding | `api.kimi.com/coding` | `KIMI_API_KEY` | kimi-for-coding |\n| `moonshot-anthropic` | Moonshot pay-as-you-go | `api.moonshot.cn/anthropic` | `MOONSHOT_API_KEY` | kimi-k2.5 |\n| `minimax-coding` | MiniMax Coding Plan | `api.minimaxi.com/anthropic` | `MINIMAX_API_KEY` | MiniMax-M3 |\n| `qwen-coding` | Alibaba Cloud Model Studio Coding Plan | `coding.dashscope.aliyuncs.com/apps/anthropic` | `DASHSCOPE_API_KEY` | qwen3.7-plus |\n| `volcengine-coding` | Volcengine Ark Coding Plan | `ark.cn-beijing.volces.com/api/coding` | `ARK_API_KEY` | doubao-seed-code-preview-latest |\n| `deepseek-anthropic` | DeepSeek pay-as-you-go | `api.deepseek.com/anthropic` | `DEEPSEEK_API_KEY` | deepseek-v4-flash |\n| `anthropic` | Anthropic API | `api.anthropic.com` | `ANTHROPIC_API_KEY` | claude-sonnet-5 / claude-haiku-4-5 |\n\nImportant notes:\n\n- **Keys are product-specific.** Kimi coding-plan keys come from\n `kimi.com/code/console` and are separate from Moonshot platform keys.\n Alibaba coding-plan keys use the `sk-sp-` prefix. Zhipu team coding keys and\n MiniMax subscription keys are also separate from their pay-as-you-go keys.\n- **Check usage terms.** Some coding plans authorize only interactive use in\n supported coding tools. Confirm the vendor's current terms before using a\n subscription key in an agent framework. Pay-as-you-go API keys are not\n subject to coding-plan restrictions.\n- **Claude subscription tokens are unsupported.** OAuth tokens produced by\n `claude setup-token` are restricted to Claude Code and claude.ai under\n Anthropic's terms. The `anthropic` preset accepts Console API keys only.\n- Newer Anthropic models such as Opus 4.7+ and Sonnet 5 reject `temperature`;\n the relevant presets omit it automatically. Other Anthropic-compatible\n vendor endpoints are unaffected.\n\n### Pay-as-you-go APIs using the OpenAI protocol\n\n| `SF_PROVIDER` | Vendor | Endpoint | Key environment variable | Default models |\n|---|---|---|---|---|\n| `deepseek` | DeepSeek | `api.deepseek.com` | `DEEPSEEK_API_KEY` | deepseek-v4-flash |\n| `zhipu` | Zhipu (China) | `open.bigmodel.cn/api/paas/v4` | `ZHIPU_API_KEY` | glm-5.2 / glm-4.7-flash |\n| `zai` | Z.ai (international) | `api.z.ai/api/paas/v4` | `ZAI_API_KEY` | glm-5.2 / glm-4.7-flash |\n| `moonshot` (alias `kimi`) | Moonshot | `api.moonshot.cn/v1` | `MOONSHOT_API_KEY` | kimi-k2.5 |\n| `minimax` | MiniMax | `api.minimaxi.com/v1` | `MINIMAX_API_KEY` | MiniMax-M3 |\n| `dashscope` (alias `qwen`) | Alibaba Cloud Model Studio | `dashscope.aliyuncs.com/compatible-mode/v1` | `DASHSCOPE_API_KEY` | qwen3.7-plus |\n| `volcengine` (aliases `doubao`, `ark`) | Volcengine Ark | `ark.cn-beijing.volces.com/api/v3` | `ARK_API_KEY` | doubao-seed-2.0-pro |\n| `openai` | OpenAI API | `api.openai.com/v1` | `OPENAI_API_KEY` | gpt-5.5 |\n| `openrouter` | OpenRouter | `openrouter.ai/api/v1` | `OPENROUTER_API_KEY` | anthropic/claude-sonnet-4.5 |\n| `siliconflow` | SiliconFlow (China) | `api.siliconflow.cn/v1` | `SILICONFLOW_API_KEY` | deepseek-ai/DeepSeek-V3.2 |\n| `gemini` | Google Gemini OpenAI compatibility layer | `generativelanguage.googleapis.com/v1beta/openai/` | `GEMINI_API_KEY` | gemini-3.5-flash |\n| `xai` | xAI | `api.x.ai/v1` | `XAI_API_KEY` | grok-4.3 |\n\nImportant notes:\n\n- DeepSeek limits output to 8,192 tokens, so SearchOS clamps the `reformat`\n profile automatically. For very large table exports, use a provider with a\n larger output window. Legacy `deepseek-chat` and `deepseek-reasoner` names are\n mapped to v4-flash.\n- OpenAI GPT-5 reasoning models reject `temperature`; their presets omit it.\n- Override `SF_API_BASE` to select international MiniMax, Moonshot, Alibaba, or\n SiliconFlow endpoints. China and international SiliconFlow accounts are not\n interchangeable.\n- Volcengine model IDs may depend on your console configuration. Override\n `SF_MODEL` when necessary.\n\n### Local deployments\n\n```bash\nSF_PROVIDER=ollama\nSF_MODEL=qwen3:32b # Required\n\nSF_PROVIDER=vllm\nSF_MODEL=Qwen/Qwen3-32B # Required; override SF_API_BASE if the port is not 8000\n```\n\nLocal services do not require a real key. The presets provide the non-empty\nplaceholders `ollama` and `EMPTY` where the client requires one.\n\n## Five profiles and their role bindings\n\nEach preset creates five profiles. Quality-sensitive judging and export roles\nuse the primary model, while high-volume extraction and synthesis roles use the\nlighter model to control cost.\n\n| Profile | Roles | Model tier | Temperature | Output limit |\n|---|---|---|---|---|\n| `main` | orchestrator / sub_agent / skill_evolver / post_mortem / skill_router | Primary | 0.7 | 16384 |\n| `judge` | judge | Primary | 0.0 | 16384 |\n| `fast` | extraction / alias_resolver / skill_runtime | Light | 0.0 | 32768 |\n| `synthesis` | synthesis | Light | 0.3 | 32768 |\n| `reformat` | reformat (evaluation table export) | Primary | 0.0 | 65536 |\n\nUse `SF_MODEL` to override the primary model and `SF_FAST_MODEL` to override the\nlight model. Presets without a separate light model fall back to the primary\none. Provider capabilities may clamp output limits, such as 8,192 for DeepSeek\nor 32,768 for the Kimi coding plan.\n\nLight-profile defaults were checked against vendor documentation in July 2026.\nExtraction inputs are often long, so models limited to an 8K context window are\nnot suitable.\n\n| Vendor | Light-profile default | Notes |\n|---|---|---|\n| Zhipu / Z.ai pay-as-you-go | `glm-4.7-flash` | Free tier, 30B, function calling and JSON support |\n| Alibaba Cloud Model Studio | `qwen3.5-flash` | 1M context; `qwen-turbo` retires on July 13, 2026 |\n| SiliconFlow | `Qwen/Qwen3-30B-A3B-Instruct-2507` | The older `Qwen/Qwen3-30B-A3B` ID is unavailable |\n| MiniMax | `MiniMax-M2.7` | The least expensive currently listed tier rather than a dedicated light model |\n| OpenAI | `gpt-5.4-mini` | The 5.5 generation has no mini/nano model |\n| Gemini | `gemini-3.1-flash-lite` | `gemini-3.5-flash-lite` does not exist |\n| OpenRouter | `google/gemini-3.5-flash` | — |\n| Moonshot, DeepSeek, xAI, Volcengine, and coding-plan presets | Primary-model fallback | Override `SF_FAST_MODEL` when your account exposes a suitable light model |\n\n## Fine-grained overrides\n\nOverrides are recursively merged with the selected preset, so changing one\nfield does not discard the others:\n\n```bash\n# Bind one role to a different profile\nSF_ROLES__EXTRACTION=main\n\n# Override fields on an existing profile (replace - with _ in environment paths)\nSF_PROFILES__MAIN__TEMPERATURE=0.3\nSF_PROFILES__MAIN__ENABLE_THINKING=true\nSF_PROFILES__FAST__MAX_TOKENS=16384\n\n# Define a custom profile and bind it to a role\nSF_PROFILES__MYPROF__MODEL=glm-5-turbo\nSF_PROFILES__MYPROF__API_BASE=https://open.bigmodel.cn/api/paas/v4\nSF_PROFILES__MYPROF__API_KEY_ENV=ZHIPU_API_KEY\nSF_ROLES__SKILL_ROUTER=myprof\n```\n\nSee `searchos/config/settings.py` for all `ModelProfile` fields, including\nprovider, thinking style, RPM/TPM limits, and extra request parameters.\n\n## Provider compatibility notes\n\n| Behavior | SearchOS handling |\n|---|---|\n| OpenAI, Gemini, and OpenRouter reject unknown request fields | `thinking_style=none`; no thinking switch is injected |\n| DashScope expects top-level `enable_thinking` | `thinking_style=enable_thinking` |\n| vLLM and SiliconFlow use `chat_template_kwargs.enable_thinking` | `thinking_style=chat_template_kwargs` |\n| Claude Opus 4.7+ and GPT-5 models reject `temperature` | `temperature_ok=False`; all profiles omit it |\n| Ollama and vLLM require a non-empty key | Presets provide `api_key_fallback` placeholders |\n| DeepSeek's Anthropic endpoint ignores `top_k`, `cache_control`, and similar fields | No special handling is required |\n\n## Search backends\n\nSearchOS also needs a Web search API. The setup wizard configures it alongside\nthe model provider.\n\n| `SF_SEARCH_PROVIDER` | Service | Key environment variable | Notes |\n|---|---|---|---|\n| `serper` | Serper.dev | `SERPER_API_KEY` | Recommended Google results backend |\n| `tavily` | Tavily | `TAVILY_API_KEY` | Requires `pip install 'searchos[tavily]'` |\n| `ragflow` | RagFlow | — | Ant Group internal backend; unavailable to external users |\n\nWithout `SF_SEARCH_PROVIDER`, SearchOS infers Serper and then Tavily from the\navailable keys. If neither key exists, it falls back to RagFlow for backward\ncompatibility. Page retrieval is configured separately through\n`SF_BROWSER_BACKEND`; the default is `jina`, and `SF_JINA_API_KEY` is\nrecommended to avoid low unauthenticated rate limits.\n\nVendor endpoints and model IDs were checked against official documentation in\nJuly 2026. Each preset in `searchos/config/providers.py` includes its source\n`doc_url`. Providers change quickly; if an endpoint or model is retired,\noverride `SF_API_BASE` or `SF_MODEL` and open an issue with the updated details.\n"}}, "searchos/config/providers.py": {"31d9e4248f0256347f208a67346a0e7931553e81": {"t": 1785674219.5606215, "n": 17355, "h": "2e5a026e592c69e6", "c": "\"\"\"Provider presets — one-knob open-source model configuration.\n\nSet ``SF_PROVIDER`` (plus the provider's API key) and every one of the 12\nmodel roles gets a working profile binding, no settings surgery required::\n\n SF_PROVIDER=zhipu-coding # GLM Coding Plan(Anthropic 协议)\n ZHIPU_API_KEY=xxx\n\n SF_PROVIDER=deepseek # DeepSeek 按量 API(OpenAI 协议)\n DEEPSEEK_API_KEY=xxx\n\nOptional knobs (all read from the environment, so they compose with .env):\n\n SF_MODEL override the preset's main model id\n SF_FAST_MODEL override the light-tier model (extraction/synthesis)\n SF_API_BASE override the endpoint (e.g. 国际站 domains)\n SF_API_KEY_ENV read the key from a different env var name\n\nPresets only generate *defaults* for ``settings.profiles`` / ``settings.roles``;\nexplicit ``SF_PROFILES__*`` / ``SF_ROLES__*`` overrides still win (they are\ndeep-merged on top by ``Settings``).\n\nEach preset expands into five tier profiles::\n\n main orchestrator / sub_agent / skill_evolver / post_mortem / skill_router\n judge judge (temperature 0)\n fast extraction / alias_resolver / skill_runtime (temperature 0)\n synthesis synthesis (temperature 0.3)\n reformat reformat (temperature 0, large output)\n\nCoding-plan presets speak the Anthropic protocol (the same endpoints the\nvendors publish for Claude Code); pay-as-you-go presets speak OpenAI\nchat/completions. NOTE: Claude Pro/Max 订阅的 OAuth token 不能在第三方框架中\n使用(Anthropic ToS 限制)——``anthropic`` 预设只支持 Console API key。\n部分厂商的 coding plan 条款仅授权交互式编程工具使用,接入前请自行确认。\n\"\"\"\n\nfrom __future__ import annotations\n\nimport os\nfrom dataclasses import dataclass, field\n\n\n@dataclass(frozen=True)\nclass ProviderPreset:\n label: str\n provider: str # \"openai_compatible\" | \"openai\" | \"anthropic\"\n api_base: str\n api_key_env: str\n main_model: str = \"\" # empty → SF_MODEL is mandatory (local deployments)\n fast_model: str = \"\" # empty → same as main\n api_key_fallback: str = \"\" # local servers need a placeholder key\n temperature_ok: bool = True # False → omit temperature entirely (gateway 400s)\n thinking_style: str = \"none\" # see ModelProfile.thinking_style\n max_output: int = 65536 # provider output-token ceiling; tiers are clamped\n doc_url: str = \"\"\n notes: str = \"\"\n extra: dict = field(default_factory=dict) # forwarded into every tier profile\n\n\n# ---------------------------------------------------------------------------\n# Registry — base_url / model id 均来自各厂商官方文档(2026-07 核实)。\n# ---------------------------------------------------------------------------\n\nPRESETS: dict[str, ProviderPreset] = {\n # --- Coding plan / Anthropic 协议 ---\n \"anthropic\": ProviderPreset(\n label=\"Anthropic 官方 API\",\n provider=\"anthropic\", api_base=\"\", # SDK default api.anthropic.com\n api_key_env=\"ANTHROPIC_API_KEY\",\n main_model=\"claude-sonnet-5\", fast_model=\"claude-haiku-4-5\",\n # Opus 4.7+/Sonnet 5/Fable 5 reject temperature/top_p/top_k outright.\n temperature_ok=False,\n doc_url=\"https://platform.claude.com/docs/en/about-claude/models/overview\",\n notes=\"仅支持 Console API key;Claude Pro/Max 订阅 OAuth token 禁止用于第三方框架(ToS)。\",\n ),\n \"zhipu-coding\": ProviderPreset(\n label=\"智谱 GLM Coding Plan(中国站)\",\n provider=\"anthropic\", api_base=\"https://open.bigmodel.cn/api/anthropic\",\n api_key_env=\"ZHIPU_API_KEY\",\n main_model=\"glm-5.2\", fast_model=\"glm-4.7\",\n doc_url=\"https://docs.bigmodel.cn/cn/coding-plan/quick-start\",\n ),\n \"zai-coding\": ProviderPreset(\n label=\"Z.ai GLM Coding Plan(国际站)\",\n provider=\"anthropic\", api_base=\"https://api.z.ai/api/anthropic\",\n api_key_env=\"ZAI_API_KEY\",\n main_model=\"glm-5.2\", fast_model=\"glm-4.7\",\n doc_url=\"https://docs.z.ai/devpack/tool/claude\",\n ),\n \"kimi-coding\": ProviderPreset(\n label=\"Kimi For Coding 订阅(kimi.com)\",\n provider=\"anthropic\", api_base=\"https://api.kimi.com/coding\",\n api_key_env=\"KIMI_API_KEY\",\n main_model=\"kimi-for-coding\",\n max_output=32768,\n doc_url=\"https://www.kimi.com/code/docs/en/third-party-tools/other-coding-agents.html\",\n notes=\"Key 在 kimi.com/code/console 创建,订阅专属,与开放平台 Key 不通用。\",\n ),\n \"moonshot-anthropic\": ProviderPreset(\n label=\"Moonshot 开放平台(Anthropic 协议,按量)\",\n provider=\"anthropic\", api_base=\"https://api.moonshot.cn/anthropic\",\n api_key_env=\"MOONSHOT_API_KEY\",\n main_model=\"kimi-k2.5\",\n doc_url=\"https://platform.kimi.com/docs/guide/agent-support\",\n ),\n \"minimax-coding\": ProviderPreset(\n label=\"MiniMax Coding Plan(中国站)\",\n provider=\"anthropic\", api_base=\"https://api.minimaxi.com/anthropic\",\n api_key_env=\"MINIMAX_API_KEY\",\n # MiniMax 无轻量档;M2.7 是在售最便宜档,作为高频小任务档。\n main_model=\"MiniMax-M3\", fast_model=\"MiniMax-M2.7\",\n doc_url=\"https://platform.minimax.io/docs/token-plan/claude-code\",\n notes=\"国际站用 SF_API_BASE=https://api.minimax.io/anthropic。\",\n ),\n \"qwen-coding\": ProviderPreset(\n label=\"阿里百炼 Qwen 编程套餐(中国站)\",\n provider=\"anthropic\",\n api_base=\"https://coding.dashscope.aliyuncs.com/apps/anthropic\",\n api_key_env=\"DASHSCOPE_API_KEY\",\n main_model=\"qwen3.7-plus\",\n doc_url=\"https://help.aliyun.com/zh/model-studio/claude-code\",\n notes=\"套餐 Key 为 sk-sp- 前缀专属 Key;条款仅授权编程工具交互式使用,接入前请自行确认。\"\n \"按量端点:https://dashscope.aliyuncs.com/apps/anthropic(普通百炼 Key)。\",\n ),\n \"volcengine-coding\": ProviderPreset(\n label=\"火山方舟 Coding Plan\",\n provider=\"anthropic\", api_base=\"https://ark.cn-beijing.volces.com/api/coding\",\n api_key_env=\"ARK_API_KEY\",\n main_model=\"doubao-seed-code-preview-latest\",\n doc_url=\"https://www.volcengine.com/docs/82379/1928262\",\n ),\n \"deepseek-anthropic\": ProviderPreset(\n label=\"DeepSeek(Anthropic 协议,按量)\",\n provider=\"anthropic\", api_base=\"https://api.deepseek.com/anthropic\",\n api_key_env=\"DEEPSEEK_API_KEY\",\n main_model=\"deepseek-v4-flash\",\n doc_url=\"https://api-docs.deepseek.com/guides/anthropic_api\",\n ),\n\n # --- OpenAI 协议(官方 / 按量 / 聚合 / 本地)---\n \"openai\": ProviderPreset(\n label=\"OpenAI 官方 API\",\n provider=\"openai\", api_base=\"https://api.openai.com/v1\",\n api_key_env=\"OPENAI_API_KEY\",\n # gpt-5.5 世代无 mini/nano,轻量档停留在 5.4 世代(2026-07 核实)。\n main_model=\"gpt-5.5\", fast_model=\"gpt-5.4-mini\",\n temperature_ok=False, # GPT-5 系推理模型固定 temperature\n doc_url=\"https://developers.openai.com/api/docs/models\",\n ),\n \"zhipu\": ProviderPreset(\n label=\"智谱 GLM 按量 API(中国站)\",\n provider=\"openai_compatible\", api_base=\"https://open.bigmodel.cn/api/paas/v4\",\n api_key_env=\"ZHIPU_API_KEY\",\n # glm-4.7-flash:免费、30B、支持 FC+JSON —— 抽取/判分档首选。\n main_model=\"glm-5.2\", fast_model=\"glm-4.7-flash\",\n doc_url=\"https://docs.bigmodel.cn\",\n ),\n \"zai\": ProviderPreset(\n label=\"Z.ai GLM 按量 API(国际站)\",\n provider=\"openai_compatible\", api_base=\"https://api.z.ai/api/paas/v4\",\n api_key_env=\"ZAI_API_KEY\",\n main_model=\"glm-5.2\", fast_model=\"glm-4.7-flash\",\n doc_url=\"https://docs.z.ai\",\n ),\n \"moonshot\": ProviderPreset(\n label=\"Moonshot/Kimi 开放平台(按量)\",\n provider=\"openai_compatible\", api_base=\"https://api.moonshot.cn/v1\",\n api_key_env=\"MOONSHOT_API_KEY\",\n # kimi-k2-turbo-preview 已下线;moonshot-v1-8k 上下文太小(抽取输入常\n # 超 8K tokens),故轻量档回落主模型,可用 SF_FAST_MODEL 自行指定。\n main_model=\"kimi-k2.5\",\n doc_url=\"https://platform.kimi.com/docs\",\n notes=\"国际站用 SF_API_BASE=https://api.moonshot.ai/v1。\",\n ),\n \"deepseek\": ProviderPreset(\n label=\"DeepSeek 按量 API\",\n provider=\"openai_compatible\", api_base=\"https://api.deepseek.com\",\n api_key_env=\"DEEPSEEK_API_KEY\",\n main_model=\"deepseek-v4-flash\",\n max_output=8192,\n doc_url=\"https://api-docs.deepseek.com\",\n notes=\"旧模型名 deepseek-chat/deepseek-reasoner 已映射到 v4-flash;思考档用 deepseek-v4-pro。\",\n ),\n \"minimax\": ProviderPreset(\n label=\"MiniMax 按量 API(中国站)\",\n provider=\"openai_compatible\", api_base=\"https://api.minimaxi.com/v1\",\n api_key_env=\"MINIMAX_API_KEY\",\n main_model=\"MiniMax-M3\", fast_model=\"MiniMax-M2.7\",\n doc_url=\"https://platform.minimax.io/docs/api-reference/text-openai-api\",\n notes=\"国际站用 SF_API_BASE=https://api.minimax.io/v1。\",\n ),\n \"dashscope\": ProviderPreset(\n label=\"阿里百炼 DashScope(按量)\",\n provider=\"openai_compatible\",\n api_base=\"https://dashscope.aliyuncs.com/compatible-mode/v1\",\n api_key_env=\"DASHSCOPE_API_KEY\",\n # qwen3.5-flash:¥0.2/¥2、1M 上下文、FC+结构化输出(qwen-turbo 已于\n # 2026-07-13 下线,勿用)。\n main_model=\"qwen3.7-plus\", fast_model=\"qwen3.5-flash\",\n thinking_style=\"enable_thinking\",\n doc_url=\"https://help.aliyun.com/zh/model-studio/\",\n notes=\"国际站用 SF_API_BASE=https://dashscope-intl.aliyuncs.com/compatible-mode/v1。\",\n ),\n \"volcengine\": ProviderPreset(\n label=\"火山方舟(按量)\",\n provider=\"openai_compatible\", api_base=\"https://ark.cn-beijing.volces.com/api/v3\",\n api_key_env=\"ARK_API_KEY\",\n main_model=\"doubao-seed-2.0-pro\",\n doc_url=\"https://www.volcengine.com/docs/82379\",\n notes=\"模型 id/接入点以方舟控制台为准,必要时用 SF_MODEL 覆盖;轻量档\"\n \"(doubao-seed-2-0-lite/mini,id 后缀以控制台为准)用 SF_FAST_MODEL 指定。\",\n ),\n \"openrouter\": ProviderPreset(\n label=\"OpenRouter 聚合\",\n provider=\"openai_compatible\", api_base=\"https://openrouter.ai/api/v1\",\n api_key_env=\"OPENROUTER_API_KEY\",\n main_model=\"anthropic/claude-sonnet-4.5\", fast_model=\"google/gemini-3.5-flash\",\n doc_url=\"https://openrouter.ai/docs\",\n notes=\"模型 id 为 vendor/model 格式;免费档带 :free 后缀。\",\n ),\n \"antchat\": ProviderPreset(\n label=\"AntChat 聚合网关\",\n provider=\"openai_compatible\", api_base=\"https://antchat.alipay.com/v1\",\n api_key_env=\"ANTCHAT_API_KEY\",\n main_model=\"\", # 聚合网关 model id 因供应商而异,必填(SF_MODEL 或模型卡片里指定)\n notes=\"类 OpenRouter 的聚合网关;模型 id 以网关支持列表为准,需自行指定。\",\n ),\n \"siliconflow\": ProviderPreset(\n label=\"硅基流动 SiliconFlow(中国站)\",\n provider=\"openai_compatible\", api_base=\"https://api.siliconflow.cn/v1\",\n api_key_env=\"SILICONFLOW_API_KEY\",\n # 30B-A3B 非思考直出、262K 上下文 —— 与内部抽取档(Qwen3.5-35B-A3B)同级。\n # 旧 id Qwen/Qwen3-30B-A3B 已下架,勿回退。\n main_model=\"deepseek-ai/DeepSeek-V3.2\",\n fast_model=\"Qwen/Qwen3-30B-A3B-Instruct-2507\",\n thinking_style=\"chat_template_kwargs\",\n doc_url=\"https://docs.siliconflow.cn\",\n notes=\"模型 id 带组织前缀且大小写敏感;国际站 SF_API_BASE=https://api.siliconflow.com/v1(账号不互通)。\",\n ),\n \"gemini\": ProviderPreset(\n label=\"Google Gemini(OpenAI 兼容层)\",\n provider=\"openai_compatible\",\n api_base=\"https://generativelanguage.googleapis.com/v1beta/openai/\",\n api_key_env=\"GEMINI_API_KEY\",\n # 轻量档确切 id 是 3.1 flash-lite(gemini-3.5-flash-lite 不存在)。\n main_model=\"gemini-3.5-flash\", fast_model=\"gemini-3.1-flash-lite\",\n doc_url=\"https://ai.google.dev/gemini-api/docs/openai\",\n ),\n \"xai\": ProviderPreset(\n label=\"xAI Grok\",\n provider=\"openai_compatible\", api_base=\"https://api.x.ai/v1\",\n api_key_env=\"XAI_API_KEY\",\n main_model=\"grok-4.3\",\n doc_url=\"https://docs.x.ai/developers/quickstart\",\n ),\n \"ollama\": ProviderPreset(\n label=\"Ollama 本地部署\",\n provider=\"openai_compatible\", api_base=\"http://localhost:11434/v1\",\n api_key_env=\"OLLAMA_API_KEY\", api_key_fallback=\"ollama\",\n main_model=\"\", # SF_MODEL 必填\n doc_url=\"https://docs.ollama.com/api/openai-compatibility\",\n ),\n \"vllm\": ProviderPreset(\n label=\"vLLM 本地部署\",\n provider=\"openai_compatible\", api_base=\"http://localhost:8000/v1\",\n api_key_env=\"VLLM_API_KEY\", api_key_fallback=\"EMPTY\",\n main_model=\"\", # SF_MODEL 必填\n thinking_style=\"chat_template_kwargs\",\n doc_url=\"https://docs.vllm.ai/en/latest/serving/openai_compatible_server.html\",\n ),\n}\n\n# 展示分组(TUI 向导表格与 web 预设列表共用)。必须覆盖全部 PRESETS —— 有\n# 覆盖性测试保证;新增预设时记得同步归组。\nPRESET_GROUPS: list[tuple[str, list[str]]] = [\n (\"coding_plan\", [\n \"zhipu-coding\", \"zai-coding\", \"kimi-coding\", \"minimax-coding\",\n \"qwen-coding\", \"volcengine-coding\",\n ]),\n (\"pay_as_you_go\", [\n \"deepseek\", \"zhipu\", \"zai\", \"moonshot\", \"minimax\", \"dashscope\",\n \"volcengine\", \"moonshot-anthropic\", \"deepseek-anthropic\",\n \"openai\", \"anthropic\", \"openrouter\", \"antchat\", \"siliconflow\", \"gemini\", \"xai\",\n ]),\n (\"local\", [\"ollama\", \"vllm\"]),\n]\n\n\ndef preset_info(name: str, preset: ProviderPreset | None = None) -> dict:\n \"\"\"预设的展示视图(web 预设列表的一项)——绝不含任何密钥值。\"\"\"\n preset = preset or PRESETS[name]\n group = next((g for g, names in PRESET_GROUPS if name in names), \"\")\n return {\n \"name\": name,\n \"label\": preset.label,\n \"group\": group,\n \"api_key_env\": preset.api_key_env,\n \"requires_key\": not preset.api_key_fallback,\n \"requires_model\": not preset.main_model,\n \"main_model\": preset.main_model,\n \"fast_model\": preset.fast_model,\n \"api_base\": preset.api_base,\n # protocol + thinking_style let the web \"new model\" form pre-fill a\n # profile's connection/thinking fields from the chosen provider.\n \"protocol\": preset.provider,\n \"thinking_style\": preset.thinking_style,\n \"temperature_ok\": preset.temperature_ok,\n \"doc_url\": preset.doc_url,\n \"notes\": preset.notes,\n }\n\n\nALIASES: dict[str, str] = {\n \"glm\": \"zhipu\",\n \"bigmodel\": \"zhipu\",\n \"glm-coding\": \"zhipu-coding\",\n \"kimi\": \"moonshot\",\n \"qwen\": \"dashscope\",\n \"doubao\": \"volcengine\",\n \"ark\": \"volcengine\",\n \"ark-coding\": \"volcengine-coding\",\n \"doubao-coding\": \"volcengine-coding\",\n \"dashscope-coding\": \"qwen-coding\",\n \"claude\": \"anthropic\",\n}\n\n# tier → (temperature, output-token ceiling)\n_TIERS: dict[str, tuple[float, int]] = {\n \"main\": (0.7, 16384),\n \"judge\": (0.0, 16384),\n \"fast\": (0.0, 32768),\n \"synthesis\": (0.3, 32768),\n # reformat emits full answer tables verbatim — needs the largest window.\n \"reformat\": (0.0, 65536),\n}\n\n_ROLE_TIERS: dict[str, str] = {\n \"orchestrator\": \"main\",\n \"sub_agent\": \"main\",\n \"skill_evolver\": \"main\",\n \"post_mortem\": \"main\",\n \"skill_router\": \"main\",\n \"judge\": \"judge\",\n \"extraction\": \"fast\",\n \"alias_resolver\": \"fast\",\n \"skill_runtime\": \"fast\",\n \"synthesis\": \"synthesis\",\n \"reformat\": \"reformat\",\n}\n\n\ndef resolve_preset(name: str) -> ProviderPreset:\n key = name.strip().lower()\n key = ALIASES.get(key, key)\n preset = PRESETS.get(key)\n if preset is None:\n known = \", \".join(sorted(PRESETS))\n raise ValueError(\n f\"Unknown SF_PROVIDER={name!r}. Available presets: {known} \"\n f\"(aliases: {', '.join(sorted(ALIASES))})\"\n )\n return preset\n\n\ndef active_provider() -> str:\n \"\"\"The SF_PROVIDER env value ('' when unset → built-in defaults apply).\"\"\"\n return os.environ.get(\"SF_PROVIDER\", \"\").strip()\n\n\ndef provider_default_profiles() -> dict[str, dict] | None:\n \"\"\"Preset-generated ``settings.profiles`` defaults, or None when SF_PROVIDER unset.\"\"\"\n name = active_provider()\n if not name:\n return None\n preset = resolve_preset(name)\n\n main = os.environ.get(\"SF_MODEL\", \"\").strip() or preset.main_model\n if not main:\n raise ValueError(\n f\"Provider preset {name!r} has no default model — set SF_MODEL \"\n f\"(e.g. the model you serve locally). Docs: {preset.doc_url}\"\n )\n fast = (\n os.environ.get(\"SF_FAST_MODEL\", \"\").strip()\n or preset.fast_model\n or main\n )\n api_base = os.environ.get(\"SF_API_BASE\", \"\").strip() or preset.api_base\n api_key_env = os.environ.get(\"SF_API_KEY_ENV\", \"\").strip() or preset.api_key_env\n\n profiles: dict[str, dict] = {}\n for tier, (temp, out_tokens) in _TIERS.items():\n # 对齐内部质量分配:judge/reformat 走主力模型(判分与导表精度敏感),\n # 只有高频抽取(fast)与合成(synthesis)走轻量档。\n profiles[tier] = {\n \"model\": fast if tier in (\"fast\", \"synthesis\") else main,\n \"provider\": preset.provider,\n \"api_base\": api_base,\n \"api_key_env\": api_key_env,\n \"api_key_fallback\": preset.api_key_fallback,\n \"temperature\": temp if preset.temperature_ok else None,\n \"max_tokens\": min(out_tokens, preset.max_output),\n \"thinking_style\": preset.thinking_style,\n **({\"extra\": dict(preset.extra)} if preset.extra else {}),\n }\n return profiles\n\n\ndef provider_default_roles() -> dict[str, str] | None:\n \"\"\"Preset-generated ``settings.roles`` defaults, or None when SF_PROVIDER unset.\"\"\"\n if not active_provider():\n return None\n return dict(_ROLE_TIERS)\n\n\n__all__ = [\n \"PRESETS\",\n \"PRESET_GROUPS\",\n \"ALIASES\",\n \"ProviderPreset\",\n \"preset_info\",\n \"resolve_preset\",\n \"active_provider\",\n \"provider_default_profiles\",\n \"provider_default_roles\",\n]\n"}}, "docs/zh/providers.md": {"31d9e4248f0256347f208a67346a0e7931553e81": {"t": 1785674219.8313305, "n": 7006, "h": "ea3d5e93078d81d3", "c": "# 模型 Provider 配置指南\n\n[English](../providers.md) | **简体中文**\n\nSearchOS 的 11 个模型角色(orchestrator、extraction、judge…)统一经 `searchos/config/models.py:get_model_for(role)` 构造,底层是 LangChain 的 `ChatOpenAI` / `ChatAnthropic`。\n\n**最快方式:首次运行 `python -m searchos` 会自动进入命令行配置向导**(选厂商 → 填 key → 写入 `.env`),或随时 `python -m searchos --setup` 重新配置。手动配置只需两行环境变量:\n\n```bash\n# .env(参考根目录 .env.example)\nSF_PROVIDER=zhipu-coding\nZHIPU_API_KEY=xxx\n```\n\n`SF_PROVIDER` 会为全部角色生成默认的 profile 绑定(分五档:`main` / `judge` / `fast` / `synthesis` / `reformat`),任何字段仍可用 `SF_PROFILES__*` / `SF_ROLES__*` 精细覆写(深合并,不会丢其余默认值)。\n\n## 预设总览\n\n### Coding Plan(Anthropic 协议,按月订阅)\n\n各厂商为 Claude Code 提供的 Anthropic 兼容端点,SearchOS 直接复用(走 `ChatAnthropic` + 自定义 `base_url`):\n\n| `SF_PROVIDER` | 厂商 | 端点 | Key 环境变量 | 默认模型 |\n|---|---|---|---|---|\n| `zhipu-coding` | 智谱 GLM Coding Plan(中国站) | `open.bigmodel.cn/api/anthropic` | `ZHIPU_API_KEY` | glm-5.2 / glm-4.7 |\n| `zai-coding` | Z.ai GLM Coding Plan(国际站) | `api.z.ai/api/anthropic` | `ZAI_API_KEY` | glm-5.2 / glm-4.7 |\n| `kimi-coding` | Kimi For Coding 订阅 | `api.kimi.com/coding` | `KIMI_API_KEY` | kimi-for-coding |\n| `moonshot-anthropic` | Moonshot 开放平台(按量) | `api.moonshot.cn/anthropic` | `MOONSHOT_API_KEY` | kimi-k2.5 |\n| `minimax-coding` | MiniMax Coding Plan | `api.minimaxi.com/anthropic` | `MINIMAX_API_KEY` | MiniMax-M3 |\n| `qwen-coding` | 阿里百炼编程套餐 | `coding.dashscope.aliyuncs.com/apps/anthropic` | `DASHSCOPE_API_KEY` | qwen3.7-plus |\n| `volcengine-coding` | 火山方舟 Coding Plan | `ark.cn-beijing.volces.com/api/coding` | `ARK_API_KEY` | doubao-seed-code-preview-latest |\n| `deepseek-anthropic` | DeepSeek(按量,无套餐) | `api.deepseek.com/anthropic` | `DEEPSEEK_API_KEY` | deepseek-v4-flash |\n| `anthropic` | Anthropic 官方 | `api.anthropic.com` | `ANTHROPIC_API_KEY` | claude-sonnet-5 / claude-haiku-4-5 |\n\n注意事项:\n\n- **Key 专属性**:Kimi 订阅 Key 在 kimi.com/code/console 创建,与开放平台不通用;阿里编程套餐 Key 为 `sk-sp-` 前缀专属;智谱团队版 Coding Key 与平台其它 Key 不通用;MiniMax 订阅 Key 与按量 Key 分开。\n- **条款限制**:阿里编程套餐条款仅授权「编程工具交互式使用」,智谱 Coding Plan 也限官方支持的编程工具——把套餐 Key 用于 agent 框架前请自行确认条款;按量 Key 无此限制。\n- **Claude 订阅不可用**:Claude Pro/Max 的 OAuth token(`claude setup-token` 产物)按 Anthropic ToS 仅限 Claude Code / claude.ai 使用,`anthropic` 预设只支持 Console API key。\n- **Anthropic 官方新模型**(Opus 4.7+ / Sonnet 5)已移除 `temperature` 参数,预设自动省略;其它厂商的 Anthropic 兼容端点不受影响。\n\n### 按量 API(OpenAI 协议)\n\n| `SF_PROVIDER` | 厂商 | 端点 | Key 环境变量 | 默认模型 |\n|---|---|---|---|---|\n| `deepseek` | DeepSeek | `api.deepseek.com` | `DEEPSEEK_API_KEY` | deepseek-v4-flash |\n| `zhipu` | 智谱按量(中国站) | `open.bigmodel.cn/api/paas/v4` | `ZHIPU_API_KEY` | glm-5.2 / glm-4.7-flash |\n| `zai` | Z.ai 按量(国际站) | `api.z.ai/api/paas/v4` | `ZAI_API_KEY` | glm-5.2 / glm-4.7-flash |\n| `moonshot`(别名 `kimi`) | Moonshot 开放平台 | `api.moonshot.cn/v1` | `MOONSHOT_API_KEY` | kimi-k2.5 |\n| `minimax` | MiniMax | `api.minimaxi.com/v1` | `MINIMAX_API_KEY` | MiniMax-M3 |\n| `dashscope`(别名 `qwen`) | 阿里百炼 | `dashscope.aliyuncs.com/compatible-mode/v1` | `DASHSCOPE_API_KEY` | qwen3.7-plus |\n| `volcengine`(别名 `doubao`/`ark`) | 火山方舟 | `ark.cn-beijing.volces.com/api/v3` | `ARK_API_KEY` | doubao-seed-2.0-pro |\n| `openai` | OpenAI 官方 | `api.openai.com/v1` | `OPENAI_API_KEY` | gpt-5.5 |\n| `openrouter` | OpenRouter 聚合 | `openrouter.ai/api/v1` | `OPENROUTER_API_KEY` | anthropic/claude-sonnet-4.5 |\n| `siliconflow` | 硅基流动(中国站) | `api.siliconflow.cn/v1` | `SILICONFLOW_API_KEY` | deepseek-ai/DeepSeek-V3.2 |\n| `gemini` | Google Gemini 兼容层 | `generativelanguage.googleapis.com/v1beta/openai/` | `GEMINI_API_KEY` | gemini-3.5-flash |\n| `xai` | xAI Grok | `api.x.ai/v1` | `XAI_API_KEY` | grok-4.3 |\n\n注意事项:\n\n- **DeepSeek** 输出上限 8192 tokens,`reformat` 档已自动钳制;超大表格导出建议换大输出窗口的厂商。旧模型名 `deepseek-chat` / `deepseek-reasoner` 已弃用,映射到 v4-flash。\n- **OpenAI GPT-5 系**为推理模型,不接受 `temperature`,预设自动省略。\n- **国际站切换**:MiniMax / Moonshot / 阿里 / 硅基流动的国际站域名用 `SF_API_BASE` 覆盖即可(见 `.env.example`;硅基流动中国站与国际站账号不互通)。\n- **火山方舟**模型 id 以控制台为准,必要时 `SF_MODEL` 覆盖。\n\n### 本地部署\n\n```bash\nSF_PROVIDER=ollama\nSF_MODEL=qwen3:32b # 必填\n\nSF_PROVIDER=vllm\nSF_MODEL=Qwen/Qwen3-32B # 必填;端口非 8000 时用 SF_API_BASE 覆盖\n```\n\n本地服务无需真实 key(预设自动填占位符 `ollama` / `EMPTY`)。\n\n## 五档 profile 与角色映射\n\n预设为每个厂商生成五个 profile,绑定关系(对齐内部质量分配:判分与导表精度敏感走主力,高频抽取与合成走轻量档降本):\n\n| profile | 角色 | 模型档 | 温度 | 输出上限 |\n|---|---|---|---|---|\n| `main` | orchestrator / sub_agent / skill_evolver / post_mortem / skill_router | 主力 | 0.7 | 16384 |\n| `judge` | judge | 主力 | 0.0 | 16384 |\n| `fast` | extraction / alias_resolver / skill_runtime | 轻量 | 0.0 | 32768 |\n| `synthesis` | synthesis | 轻量 | 0.3 | 32768 |\n| `reformat` | reformat(评测导表,需最大窗口) | 主力 | 0.0 | 65536 |\n\n主力模型用 `SF_MODEL` 覆盖,轻量档用 `SF_FAST_MODEL` 覆盖(预设未配轻量档时回落主力)。输出上限会被厂商能力钳制(如 DeepSeek 8192、Kimi 订阅 32768)。\n\n各预设的轻量档默认值(2026-07 核实;抽取输入较长,8K 上下文的小杯模型不可用):\n\n| 厂商 | 轻量档默认 | 备注 |\n|---|---|---|\n| 智谱 / Z.ai 按量 | `glm-4.7-flash` | 免费、30B、支持 FC+JSON |\n| 阿里百炼 | `qwen3.5-flash` | ¥0.2/¥2、1M 上下文(`qwen-turbo` 已于 2026-07-13 下线) |\n| 硅基流动 | `Qwen/Qwen3-30B-A3B-Instruct-2507` | 与内部抽取档同级;旧 id `Qwen/Qwen3-30B-A3B` 已下架 |\n| MiniMax | `MiniMax-M2.7` | 无真正轻量档,M2.7 为在售最便宜档 |\n| OpenAI | `gpt-5.4-mini` | 5.5 世代无 mini/nano,轻量档在 5.4 世代 |\n| Gemini | `gemini-3.1-flash-lite` | `gemini-3.5-flash-lite` 不存在 |\n| OpenRouter | `google/gemini-3.5-flash` | |\n| Moonshot / DeepSeek / xAI / 火山 / coding plan 系 | 回落主力 | Moonshot turbo 已下线、火山 lite/mini id 需在控制台确认后用 `SF_FAST_MODEL` 指定;DeepSeek v4-flash 本身即便宜档 |\n\n## 精细覆写\n\n所有覆写与预设**深合并**——只改你写的字段,其余保持预设值:\n\n```bash\n# 单角色换绑(比如抽取角色换更便宜的模型档)\nSF_ROLES__EXTRACTION=main\n\n# 单 profile 字段覆写(profile 名里的 - 在环境变量里写成 _)\nSF_PROFILES__MAIN__TEMPERATURE=0.3\nSF_PROFILES__MAIN__ENABLE_THINKING=true\nSF_PROFILES__FAST__MAX_TOKENS=16384\n\n# 完全自定义一个 profile 并绑给某角色\nSF_PROFILES__MYPROF__MODEL=glm-5-turbo\nSF_PROFILES__MYPROF__API_BASE=https://open.bigmodel.cn/api/paas/v4\nSF_PROFILES__MYPROF__API_KEY_ENV=ZHIPU_API_KEY\nSF_ROLES__SKILL_ROUTER=myprof\n```\n\n`ModelProfile` 的完整字段(provider、thinking_style、rpm/tpm 限速、extra 透传等)见 `searchos/config/settings.py`。\n\n## 厂商怪癖速查\n\n| 怪癖 | 处理方式 |\n|---|---|\n| OpenAI / Gemini / OpenRouter 拒收未知 body 参数 | 预设 `thinking_style=none`,不注入任何 thinking 开关 |\n| DashScope 用顶层 `enable_thinking` | 预设 `thinking_style=enable_thinking` |\n| vLLM / 硅基流动用 `chat_template_kwargs.enable_thinking` | 预设 `thinking_style=chat_template_kwargs` |\n| Claude Opus 4.7+ / GPT-5 系拒收 `temperature` | 预设 `temperature_ok=False`,全档省略 |\n| Ollama / vLLM 要求非空 key | 预设 `api_key_fallback` 占位 |\n| DeepSeek Anthropic 端点忽略 `top_k`、`cache_control` 等 | 无需处理,静默忽略 |\n\n## 搜索后端\n\n模型之外还需要一个 Web 搜索 API(配置向导会一并引导):\n\n| `SF_SEARCH_PROVIDER` | 服务 | Key 环境变量 | 说明 |\n|---|---|---|---|\n| `serper` | Serper.dev | `SERPER_API_KEY` | Google 结果,推荐;serper.dev 注册 |\n| `tavily` | Tavily | `TAVILY_API_KEY` | 需 `pip install 'searchos[tavily]'` |\n| `ragflow` | RagFlow | — | 蚂蚁内网接口,外部不可用 |\n\n不设 `SF_SEARCH_PROVIDER` 时按已有 key 自动推断(serper → tavily),都没有则回落 ragflow(向后兼容内部用法)。页面抓取后端另由 `SF_BROWSER_BACKEND` 控制(默认 `jina`,建议配 `SF_JINA_API_KEY`)。\n\n各端点与模型 id 核实于 2026-07 各厂商官方文档(`searchos/config/providers.py` 每个预设附 `doc_url`)。厂商迭代快,如遇 404/模型下线,用 `SF_API_BASE` / `SF_MODEL` 覆盖并提 issue。\n"}}}}