Files

1 line
40 KiB
JSON
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{"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"}}}}