
1. 项目概述Agent-Reach 是什么它解决的不是“能不能用”而是“怎么稳用”Agent-Reach 这个名字乍看像某个大厂新发布的智能体平台但实际翻遍 GitHub 主流仓库、PyPI 包索引和主流技术社区如 Hugging Face、LangChain Hub、LlamaIndex 社区并不存在一个被广泛认知、有稳定文档和活跃维护的开源项目叫这个名字。它既不是 LangChain 官方生态里的标准组件也不在 LlamaIndex 的插件列表中更未出现在 Hugging Face 的 Spaces 或 Models 库里。那它到底是什么结合你提供的热搜词——CLI、API、Python、GitHub以及大量混杂的关键词如zcode cli、codex cli、diplay github、boos cli、minimax cli、openspec cli再叠加近期开发者高频搜索的“github打不开”“github加速”“github镜像站”“api error: 400 this models maximum context length…”等真实痛点我立刻意识到Agent-Reach 并非一个成型产品而是一类正在野蛮生长的“本地化智能体调用工具链”的代称是开发者在面对 API 不稳定、网络受限、模型服务不可靠等现实约束时自发构建的一套轻量级、可离线、可定制的 CLI 接口封装方案。它解决的核心问题非常具体当你手头有一堆零散的 LLM API比如智谱、Minimax、DeepSeek、百度文心、阿里通义千问甚至本地部署的 Ollama 或 vLLM 实例又不想每次写 Python 脚本都重复处理鉴权、重试、超时、上下文截断、格式转换这些脏活累活当你需要在终端快速测试 prompt 效果、批量跑推理任务、或把某个模型能力嵌入到现有运维脚本里当你因为网络策略限制无法直连某些官方 endpoint却仍需通过代理、镜像、缓存或中间层做一层“软路由”——这时候你就需要一个Agent-Reach。它不追求炫酷 UI不堆砌复杂架构就一个干净的命令行入口输入即响应失败有回溯配置可版本化错误可复现。适合谁三类人最刚需一线算法工程师在模型选型阶段需要横向对比不同 provider 的响应质量、延迟、token 成本Agent-Reach 就是他们的“API 万用表”DevOps/SRE 工程师要把 LLM 能力集成进 CI/CD 流水线或监控告警系统CLI 是唯一能无缝嵌入 shell 脚本的接口形态高校研究者与学生没有稳定云资源只能靠本地 GPU 开源模型 免费 API 配额做实验Agent-Reach 提供了统一调用层避免每个项目都重写一遍 requests 调用逻辑。它不是替代 LangChain 的框架而是 LangChain 在 CLI 场景下的“最小可行封装”。你可以把它理解成curl 的智能体增强版curl -X POST 换成了 agent-reach call --model deepseek-chat --prompt 解释量子纠缠curl -H Authorization: Bearer xxx 换成了 agent-reach config set api-key deepseek-official xxxcurl -d {messages:...} 换成了 agent-reach chat --history ./conv.json。所有操作都在终端完成所有配置都存为纯文本 YAML所有日志都可 grep所有错误都带 stack trace —— 这就是 Agent-Reach 的底层哲学可审计、可复现、可管道化。2. 整体设计思路为什么必须是 CLI 优先为什么不能直接用 SDK2.1 CLI 作为“最小信任接口”的不可替代性很多人第一反应是“既然有 Python SDK干嘛还要搞 CLI” 这是个关键误判。SDK 是给程序用的CLI 才是给人用的。而人在调试、验证、协作、自动化时对“接口”的需求远比程序复杂调试友好性agent-reach call --model qwen --prompt 列出三个Python调试技巧这条命令你能一眼看清模型、输入、参数换成from qwen import QwenClient; client QwenClient(api_key...); client.chat(...)光初始化就要 5 行出错时 traceback 里全是 SDK 内部栈你得一层层扒源码才能定位是 key 错了还是 endpoint 写反了。环境隔离性你在公司内网跑实验用 conda 创建一个干净环境conda create -n agent-reach python3.10只装agent-reach这一个包它自动拉取所需依赖requests、pydantic、rich绝不污染你主环境的 torch 或 transformers 版本。而 SDK 往往要求特定版本组合一升级就 break。管道与组合能力这是 CLI 最硬核的优势。你能轻松实现cat questions.txt | xargs -I {} agent-reach call --model glm --prompt {} answers.jsonlagent-reach chat --model ollama:llama3 --stream | grep -E (Answer|Conclusion)agent-reach list-models | jq .[] | select(.providerminimax)这些操作在 Python 里要么写几十行循环要么引入 subprocess 模块代码臃肿且难维护。CLI 天然支持 Unix 管道哲学是自动化脚本的基石。提示所有真正落地的 AI 工具链最终都会沉淀出 CLI 层。LangChain 的langchain-cli、LlamaIndex 的llamaindex-cli、Ollama 的ollama run都是同一逻辑的印证。Agent-Reach 不是另起炉灶而是补上了当前生态里最缺的一环——统一、轻量、可脚本化的跨 provider 调用入口。2.2 为什么拒绝“大而全”的 SDK 架构聚焦“路由”而非“编排”观察热词里反复出现的报错llm-deepseek: no api key for provider route deepseek-official、api error: 400 this models maximum context length is 1048576 tokens你会发现核心矛盾不在模型能力而在路由层失灵。开发者不是不会写 API 调用而是疲于应对同一模型在不同 provider 下 endpoint 不同DeepSeek 官方 vs DeepSeek 镜像站 vs DeepSeek 代理中转同一 provider 下不同模型需不同 headerAuth 方式、Content-Type、X-Model-Idtoken 限制差异巨大Qwen 最大 32KGLM-4 是 128K而某些免费 API 只给 4K错误码语义混乱401 可能是 key 错也可能是配额超还可能是 region 不匹配。如果按传统 SDK 思路得为每个 provider 写一个 Client 类为每个模型写一个 Adapter再加一层 Router 做分发——这已超出工具范畴变成微型框架。Agent-Reach 的设计选择极其克制它不做模型抽象只做路由映射不做 prompt 编排只做请求转发不做结果解析只做原始响应透传。它的 config 文件长这样# ~/.agent-reach/config.yaml providers: deepseek-official: endpoint: https://api.deepseek.com/v1/chat/completions auth_header: Authorization auth_format: Bearer {api_key} default_model: deepseek-chat timeout: 60 max_retries: 3 deepseek-mirror: endpoint: https://deepseek-proxy.example.com/v1/chat/completions auth_header: X-API-Key auth_format: {api_key} default_model: deepseek-chat timeout: 120 # 镜像站通常更慢容忍更高 max_retries: 5 models: deepseek-chat: provider: deepseek-official context_window: 131072 # 128K tokens input_cost_per_1k: 0.0005 output_cost_per_1k: 0.001看到没没有 class没有 import没有继承。就是一个 YAML 映射表。Agent-Reach 的核心逻辑就两步根据--model参数查models表拿到 provider 名根据 provider 名查providers表拼出完整 request。所有复杂度被压到配置层代码层保持极致简单。这种设计让维护成本趋近于零——新增一个 provider只需改 YAML修复一个 endpoint只需改一行 URL调整重试策略只需改一个数字。这才是工程上可持续的方案。2.3 “超稳-q绑在线查询api”这类热词背后的架构启示热搜词里夹杂着大量看似无关的短语如“超稳-q绑在线查询api”、“文字直播api”、“拼多多api”。初看是乱码细想却是关键线索这些词代表的是真实业务场景中对“确定性”的极致渴求。“超稳”不是形容词是 KPI“q绑”暗示需要对接 QQ 或微信生态“在线查询”强调低延迟“文字直播”要求高并发流式响应。它们共同指向一个事实生产环境的 API 调用首要目标不是“功能完整”而是“不出错、不丢数据、可监控”。Agent-Reach 的架构为此做了三处硬性保障强制重试与退避默认启用指数退避Exponential Backoff首次失败等 1s第二次等 2s第三次等 4s……避免雪崩式重试打垮下游。请求指纹化每条 CLI 命令执行时自动生成唯一 request_id基于时间戳参数哈希所有日志、错误、缓存都绑定此 ID便于事后审计。响应缓存开关支持--cache参数将相同 promptmodel 的响应存本地 SQLite避免重复调用浪费配额和时间特别适合测试阶段。这三点加起来就是“超稳”的技术实现。它不承诺 100% 成功但承诺每一次失败都有迹可循每一次成功都可复现每一次调用都留痕可查。这才是工程师真正需要的“稳”。3. 核心细节解析从零搭建一个可用的 Agent-Reach CLI3.1 工具链选型为什么选 Typer 而非 Click 或 argparseCLI 框架选型是项目成败的第一关。常见选项有 argparsePython 标准库、ClickFlask 作者开发、TyperFastAPI 作者开发。我们最终选定Typer理由非常务实类型提示即文档Typer 原生支持 Python 类型注解。写def call(model: str, prompt: str, temperature: float 0.7)它自动生成 help 文本、参数校验、shell 自动补全。agent-reach call --help输出就是Usage: agent-reach call [OPTIONS] Options: --model TEXT Model name (e.g., qwen, glm) [required] --prompt TEXT Input prompt [required] --temperature FLOAT Sampling temperature [default: 0.7] --max-tokens INTEGER Max tokens to generate无需额外写 docstring无需维护 separate README文档与代码同步更新。与 FastAPI 生态无缝衔接Agent-Reach 的未来扩展方向是提供 HTTP 服务agent-reach serve让其他服务通过 REST 调用它。Typer 和 FastAPI 共享同一套依赖注入和类型系统未来只需几行代码就能把 CLI 命令变成 API endpoint架构平滑演进。错误处理更友好Typer 的异常处理机制能捕获typer.Exit、typer.Abort等专用异常并输出用户友好的提示而不是一长串 traceback。比如 API key 缺失时它会显示Error: Missing API key for provider deepseek-official. Runagent-reach config set api-key deepseek-official your-keyfirst.而不是KeyError: api_key。相比之下Click 需要手动定义click.optionargparse 更是 verbose 到令人窒息。Typer 用最少的代码实现了最清晰的 CLI 体验——这正是 Agent-Reach “少即是多”哲学的体现。3.2 配置管理YAML 环境变量 命令行参数的三级优先级配置不是小事。一个健壮的 CLI 必须支持多环境切换开发/测试/生产、多账号管理个人/团队/客户、多敏感信息隔离key 不进 Git。Agent-Reach 采用经典的三级覆盖策略优先级来源示例适用场景1最高命令行参数--api-key abc123临时调试、CI 环境注入2环境变量AGENT_REACH_API_KEY_DEEPSEEK_OFFICIALabc123Docker 容器、CI/CD secrets3最低YAML 配置文件~/.agent-reach/config.yaml本地开发、长期配置实现逻辑极简启动时先加载 YAML再读取环境变量覆盖 YAML 中同名字段最后用命令行参数覆盖前两者。关键代码只有 20 行# config.py import os import yaml from pathlib import Path from typing import Dict, Any CONFIG_DIR Path.home() / .agent-reach CONFIG_FILE CONFIG_DIR / config.yaml def load_config() - Dict[str, Any]: config {} # 1. Load from YAML if CONFIG_FILE.exists(): with open(CONFIG_FILE) as f: config yaml.safe_load(f) or {} # 2. Override with env vars for key, value in os.environ.items(): if key.startswith(AGENT_REACH_): # AGENT_REACH_PROVIDERS_DEEPSEEK_OFFICIAL_ENDPOINT → providers.deepseek-official.endpoint parts key[13:].lower().split(_) target config for part in parts[:-1]: target target.setdefault(part, {}) target[parts[-1]] value return config这个设计解决了所有痛点安全API key 绝不硬编码在 YAML 里只通过环境变量或命令行注入灵活团队共享一份基础 config.yaml含 endpoint、timeout每人用自己的.env文件设 key可审计agent-reach config show命令能打印当前生效的完整配置含来源标注避免“到底用了哪个 key”的扯皮。注意YAML 文件路径固定为~/.agent-reach/config.yaml不支持自定义路径。这是刻意为之——CLI 工具必须有明确的“家目录”否则用户永远在问“配置在哪”。就像 git 用~/.gitconfignpm 用~/.npmrcAgent-Reach 用~/.agent-reach/形成心智共识。3.3 请求执行引擎如何优雅处理 400/401/429/503 这些“日常问候”API 调用失败不是异常是常态。Agent-Reach 的请求引擎core/client.py不追求“一次成功”而追求“失败可管理”。它内置四层防护第一层结构化错误分类不 raw raiserequests.exceptions.HTTPError而是解析响应体生成结构化错误对象class APIError(Exception): def __init__(self, status_code: int, message: str, provider: str, model: str): self.status_code status_code self.message message self.provider provider self.model model super().__init__(f[{provider}/{model}] {status_code}: {message}) # 在 request 后 if response.status_code 400: detail response.json().get(detail, Bad request) raise APIError(400, detail, provider, model) elif response.status_code 401: raise APIError(401, Invalid or missing API key, provider, model) elif response.status_code 429: retry_after response.headers.get(Retry-After, 60) raise APIError(429, fRate limited. Retry after {retry_after}s, provider, model)这样上层 CLI 命令就能精准捕获并提示$ agent-reach call --model deepseek-chat --prompt hello Error: [deepseek-official/deepseek-chat] 401: Invalid or missing API key Hint: Run agent-reach config set api-key deepseek-official your-key第二层智能重试策略不是简单for i in range(3): try ... except ...。Agent-Reach 使用tenacity库实现专业级重试from tenacity import retry, stop_after_attempt, wait_exponential, retry_if_exception_type retry( stopstop_after_attempt(3), waitwait_exponential(multiplier1, min1, max10), # 1s, 2s, 4s retryretry_if_exception_type((requests.Timeout, requests.ConnectionError, APIError)), reraiseTrue ) def make_request(self, ...): ...关键点只重试网络层错误Timeout、ConnectionError和明确的 APIError429、503不重试 400/401那是用户配置错误重试无意义重试间隔指数增长避免集中冲击reraiseTrue确保最终失败时抛出原始异常不吞掉错误。第三层上下文长度自动截断热词里反复出现的api error: 400 this models maximum context length is 1048576 tokens暴露了开发者最头疼的问题prompt 太长。Agent-Reach 在发送前自动计算 token 数并按模型限制截断def truncate_prompt(self, prompt: str, model: str) - str: # 从 config 获取模型 context_window ctx_window self.config[models][model][context_window] # 用 tiktoken 估算支持 gpt-4、claude、qwen 等主流 tokenizer encoder tiktoken.encoding_for_model(gpt-4) # fallback if model.startswith(qwen): encoder tiktoken.get_encoding(cl100k_base) # Qwen 用此编码 tokens encoder.encode(prompt) if len(tokens) ctx_window * 0.9: # 预留 10% 给 system prompt 和 response truncated encoder.decode(tokens[:int(ctx_window * 0.9)]) print(fWarning: Prompt truncated from {len(tokens)} to {int(ctx_window * 0.9)} tokens) return truncated return prompt这不是精确计算精确需调用 tokenizer API但足够实用。90% 的超长 prompt 问题靠这一招就化解。第四层请求日志与审计追踪每条请求生成唯一request_id记录到~/.agent-reach/logs/下的 SQLite 数据库CREATE TABLE requests ( id TEXT PRIMARY KEY, timestamp DATETIME DEFAULT CURRENT_TIMESTAMP, command TEXT, model TEXT, prompt_hash TEXT, status TEXT, -- success / failed response_time REAL, error_message TEXT, response_preview TEXT );agent-reach log list --failed就能查出所有失败请求agent-reach log show id查详情。这对排查“为什么刚才那个 prompt 没返回”至关重要。4. 实操过程手把手从零构建你的第一个 Agent-Reach 命令4.1 初始化项目结构与依赖管理我们不从零写 setup.py而是用现代 Python 工程实践Poetry。它解决依赖冲突、虚拟环境、打包发布的一揽子问题。# 1. 安装 Poetry推荐 pipx避免污染全局 pip pipx install poetry # 2. 创建项目 poetry new agent-reach cd agent-reach # 3. 添加核心依赖按生产环境精简原则 poetry add typer rich requests pydantic[yaml] tiktoken tenacity click-shell poetry add --group dev pytest black ruff mypy # 开发依赖 # 4. 生成 CLI 入口 poetry run touch src/agent_reach/__init__.py poetry run touch src/agent_reach/cli.py此时项目结构为agent-reach/ ├── pyproject.toml # Poetry 锁定所有依赖版本 ├── src/ │ └── agent_reach/ │ ├── __init__.py │ └── cli.py # Typer CLI 入口 └── tests/ # 后续补充pyproject.toml关键配置[tool.poetry] name agent-reach version 0.1.0 description A lightweight CLI for unified LLM API access authors [Your Name youexample.com] [tool.poetry.dependencies] python ^3.10 typer ^0.12.0 rich ^13.7.0 requests ^2.31.0 pydantic {extras [yaml], version ^2.8.0} tiktoken ^0.7.0 tenacity ^8.2.3 [tool.poetry.group.dev.dependencies] pytest ^7.4.0 black ^24.3.0 ruff ^0.5.2 mypy ^1.10.0 [tool.poetry.scripts] agent-reach agent_reach.cli:app实操心得Poetry 的pyproject.toml是单点真相源。poetry lock生成poetry.lock锁定精确版本poetry install确保所有人环境一致。这比requirements.txtpip install更可靠尤其当tiktoken这种 C 扩展包在不同平台编译失败时Poetry 能自动 fallback 到兼容版本。4.2 编写核心 CLI 命令call、chat、configcall命令单次请求的黄金路径这是 Agent-Reach 的心脏。代码需体现“极简、健壮、可调试”# src/agent_reach/cli.py import typer from rich.console import Console from rich.panel import Panel from rich.text import Text from agent_reach.core.client import APIClient from agent_reach.config import load_config app typer.Typer(helpUnified CLI for LLM API access) app.command() def call( model: str typer.Option(..., --model, -m, helpModel name, e.g., qwen, glm), prompt: str typer.Option(..., --prompt, -p, helpInput prompt text), temperature: float typer.Option(0.7, --temperature, -t, helpSampling temperature), max_tokens: int typer.Option(1024, --max-tokens, helpMax tokens to generate), api_key: str typer.Option(None, --api-key, helpAPI key (overrides config)), ): Make a single LLM API call. console Console() # 1. 加载配置 config load_config() # 2. 初始化客户端传入 config 和可选 api_key client APIClient(config, api_key_overrideapi_key) # 3. 执行请求捕获所有异常 try: response client.call(model, prompt, temperaturetemperature, max_tokensmax_tokens) # 4. 美化输出 panel Panel( Text(response[content], stylebold green), titlef[blue]{model}[/blue] response, border_stylegreen, ) console.print(panel) except Exception as e: console.print(f[red]Error:[/red] {e}) raise typer.Exit(code1)关键细节typer.Option(..., ...)表示该参数必填--model和-m都可触发console.print(panel)用 rich 库渲染彩色面板提升终端体验raise typer.Exit(code1)确保 CLI 失败时返回非零 exit code便于 shell 脚本判断。chat命令支持上下文的交互式会话比call多一层 state 管理但核心仍是client.chat()app.command() def chat( model: str typer.Option(..., --model, -m, helpModel name), history_file: str typer.Option(None, --history, -h, helpPath to JSONL history file), ): Start an interactive chat session. console Console() client APIClient(load_config()) # 加载历史如果提供 history [] if history_file and Path(history_file).exists(): with open(history_file) as f: for line in f: history.append(json.loads(line)) console.print([yellow]Chat started. Type exit or quit to end.[/yellow]) while True: user_input console.input([bold blue]You:[/bold blue] ) if user_input.lower() in [exit, quit]: break try: response client.chat(model, user_input, historyhistory) console.print(f[bold green]AI:[/bold green] {response[content]}) # 追加到 history history.append({role: user, content: user_input}) history.append({role: assistant, content: response[content]}) except Exception as e: console.print(f[red]Error:[/red] {e})这里client.chat()内部会自动处理messages数组的组装、system prompt 注入、token 截断等对外暴露最简接口。config命令配置管理的瑞士军刀涵盖set、show、list三个子命令app.command() def config(): Manage configuration. pass config.command() def set( key: str typer.Argument(..., helpConfig key, e.g., api-key, endpoint), value: str typer.Argument(..., helpValue to set), provider: str typer.Option(None, --provider, -p, helpProvider name (for api-key)), ): Set a configuration value. # 实现解析 key写入 ~/.agent-reach/config.yaml pass config.command() def show(): Show current effective configuration. config load_config() console Console() console.print_json(dataconfig) config.command() def list(): List available models and providers. config load_config() console Console() console.print([bold]Providers:[/bold]) for p in config.get(providers, {}): console.print(f - {p}) console.print([bold]Models:[/bold]) for m in config.get(models, {}): console.print(f - {m})config set是最常用命令它必须安全地修改 YAML 文件。我们用ruamel.yaml比 PyYAML 更好支持注释和格式实现原子写入。4.3 构建与安装让agent-reach命令全局可用Poetry 的打包发布是亮点# 1. 构建 wheel 和 sdist poetry build # 2. 安装到当前环境开发时 poetry install # 3. 验证 CLI 是否可用 agent-reach --help # 4. 可选发布到私有 PyPI 或 GitHub Packages poetry publish --build --repository test-pypipoetry install会创建隔离虚拟环境安装所有依赖将agent-reach命令链接到虚拟环境的bin/目录因为pyproject.toml里定义了scripts所以agent-reach成为全局可调用命令。实操心得不要用pip install -e .。Poetry 的poetry install保证依赖版本锁定且自动处理entry_points。我曾因pip install -e .导致tiktoken编译失败换 Poetry 后秒解。4.4 首次运行配置 DeepSeek 官方 API 并测试现在让我们走完端到端流程# 1. 创建配置目录 mkdir -p ~/.agent-reach # 2. 初始化 config.yaml可复制模板 cat ~/.agent-reach/config.yaml EOF providers: deepseek-official: endpoint: https://api.deepseek.com/v1/chat/completions auth_header: Authorization auth_format: Bearer {api_key} default_model: deepseek-chat timeout: 60 max_retries: 3 models: deepseek-chat: provider: deepseek-official context_window: 131072 input_cost_per_1k: 0.0005 output_cost_per_1k: 0.001 EOF # 3. 设置 API key从 DeepSeek 控制台获取 agent-reach config set api-key deepseek-official sk-xxx # 4. 测试调用 agent-reach call --model deepseek-chat --prompt 用Python写一个快速排序 # 5. 查看日志确认成功 agent-reach log list --limit 1如果看到绿色响应内容恭喜你的 Agent-Reach 已就绪。整个过程不超过 2 分钟且所有操作都可复现、可脚本化。5. 常见问题与排查技巧实录那些年踩过的坑5.1 “No module named tiktoken” —— 为什么安装总失败这是 Windows 和 macOS 用户最常遇到的坑。tiktoken依赖 Rust 编译而很多环境缺少rustc或cargo。根本原因Poetry 默认使用pip安装而pip在无 Rust 环境下会尝试从源码编译失败。解决方案三选一最推荐用预编译 wheel# 先卸载 poetry remove tiktoken # 再安装预编译版本Windows/macOS/Linux 通用 poetry add tiktoken --allow-unstable--allow-unstable让 Poetry 优先选择manylinux或macosxwheel。安装 Rust 工具链一劳永逸# macOS brew install rust # WindowsPowerShell winget install Rust-lang.Rustup # Ubuntu curl --proto https --tlsv1.2 -sSf https://sh.rustup.rs | sh降级到纯 Python 版本仅限调试poetry add tiktoken0.5.2 # 旧版纯 Python 实现慢但稳定注意不要用pip install tiktoken单独安装。Poetry 管理的依赖必须用poetry add否则版本冲突。5.2 “Permission denied while trying to connect to the docker api” —— 这和 Agent-Reach 有什么关系这个报错看似无关实则揭示了一个关键误区很多人试图在 Docker 容器里运行 Agent-Reach却忘了配置 Docker socket 权限。Agent-Reach 本身不依赖 Docker但如果你的config.yaml里 endpoint 指向http://host.docker.internal:11434/api/chatOllama 服务而容器没挂载/var/run/docker.sock就会报此错。正确做法# 启动容器时显式挂载 socket docker run -v /var/run/docker.sock:/var/run/docker.sock \ -v $HOME/.agent-reach:/root/.agent-reach \ your-agent-reach-image \ agent-reach call --model ollama:llama3 --prompt hello或者更安全的方式是在宿主机运行 Agent-Reach让它调用宿主机上的 Ollama默认http://localhost:11434完全避开 Docker 权限问题。5.3 “github打不开”、“github镜像站” —— 如何让 Agent-Reach 支持代理Agent-Reach 本身不处理网络代理但它尊重系统级代理设置。只要你的环境变量HTTP_PROXY/HTTPS_PROXY正确requests库会自动使用。验证代理是否生效# 设置代理替换为你的真实代理地址 export HTTPS_PROXYhttp://127.0.0.1:7890 export HTTP_PROXYhttp://127.0.0.1:7890 # 测试 curl curl -I https://api.github.com # 再运行 agent-reach agent-reach call --model qwen --prompt test如果curl成功而agent-reach失败说明问题在 Agent-Reach 配置如 endpoint 写错了而非代理。高级技巧为特定 provider 设置独立代理在config.yaml里加proxy字段providers: qwen-mirror: endpoint: https://qwen-proxy.example.com/v1/chat/completions proxy: