首页 / 资讯中心 / 文章详情

Agent-Reach:面向生产环境的声明式API路由与执行中枢

Agent-Reach:面向生产环境的声明式API路由与执行中枢 ★ FEATURED ARTICLE
1. 项目概述Agent-Reach 是什么它解决的不是“调 API”这个表层问题而是开发者在真实工程场景中反复踩坑的系统性断点Agent-Reach 这个名字乍看像某个新出的大模型代理框架但结合 CLI、API、YouTube、Reddit 这些高频热词再细看网络搜索中反复出现的报错片段——“llm-deepseek: no api key for provider route deepseek-official”、“api error: 400 this models maximum context length is 1048576 tokens”、“permission denied while trying to connect to the docker api”——我立刻意识到这不是一个玩具级 demo而是一个面向真实生产环境的 API 路由与执行中枢。它本质是把“调用一个 API”这件事从零散的手动 curl、临时写的 Python 脚本、混乱的环境变量管理升级为可配置、可复用、可审计、可回滚的标准化操作单元。我在过去三年里带过 7 个 AI 工具链项目几乎每个都卡在同一个环节当业务方说“把 YouTube 视频标题摘要一下”开发同学第一反应不是写逻辑而是翻文档查 YouTube Data API 的 OAuth 流程、找 Reddit 的 rate limit 配置、确认 DeepSeek 的 token 限制是否够用、再手动拼接 curl 命令——这中间任何一环出错整个链路就断掉。Agent-Reach 就是为终结这种“每次调 API 都像重新学一遍”的状态而生。它不替代 LLM也不封装模型而是做那个站在所有 API 背后、默默处理认证、路由、重试、限流、日志、错误归因的“交通指挥员”。适合三类人需要快速验证多源数据整合的产品经理、被 API 碎片化折磨的全栈工程师、以及正在搭建内部 AI 工具平台的技术负责人。它不是让你“更方便地调 API”而是让你彻底忘记“调 API”这个动作本身。2. 整体架构设计与核心思路拆解为什么必须放弃“写脚本”的思维转向声明式路由2.1 传统方式的三大死穴从“能跑通”到“能维护”之间隔着一堵墙我最早接触 Agent-Reach 是在帮一家做跨境内容分析的团队重构他们的数据采集流程。他们原有方案是用 Python 写了 12 个独立脚本分别对接 YouTube、Reddit、Twitter 和几个小众论坛的 API。表面看每个脚本都能跑但实际运维时问题层出不穷认证黑洞YouTube 需要 OAuth2 refresh tokenReddit 要 client_id secret user_agentDeepSeek 只要一个 API Key而 Minimax 又要求 bearer token custom header。这些凭据混在代码里有人直接 commit 到 GitHub有人存在本地 .env有人甚至写死在 config.py 里。一次安全审计光凭据泄露风险就让整个项目暂停两周。错误不可见某次 Reddit 接口返回 429Too Many Requests脚本直接抛异常退出下游任务全部中断。没人知道是配额用完、IP 被限还是对方服务抖动。日志里只有一行 “HTTPError: 429 Client Error”没有上下文没有重试记录没有失败前后的请求 ID。扩展即灾难当业务方提出“加一个拼多多商品价格比对功能”时开发同学不是加几行代码而是得先研究拼多多开放平台文档搞懂它的签名算法HMAC-SHA256 timestamp nonce再适配到现有脚本结构里——结果改完 YouTube 模块的认证逻辑Reddit 模块反而因为共用了一个全局 session 对象而开始 401。Agent-Reach 的设计哲学就是把这三座大山一次性推平。它不提供“怎么调 API”的代码而是定义“API 应该被怎样调用”的契约。核心是三层抽象Provider 层每个 API 服务商YouTube、Reddit、DeepSeek被抽象为一个 Provider它封装了该服务商特有的认证方式、基础 URL、默认 headers、rate limit 策略、错误码映射表。比如 Reddit Provider 内置了对X-Ratelimit-Remainingheader 的自动解析当剩余请求数 5 时自动触发降级策略YouTube Provider 则内置了 OAuth2 token 自动刷新逻辑只要配置好 refresh_token后续请求完全无感。Route 层这是 Agent-Reach 的心脏。一个 Route 不是一段代码而是一个 YAML 或 JSON 文件声明了“调用谁、传什么、期望什么响应、失败怎么办”。例如一个 YouTube 标题摘要 Route会明确指定使用 youtube-providerendpoint 是/videosmethod 是 GETquery 参数包含id和parttitle,snippetresponse schema 要求items[].snippet.title存在失败时 fallback 到本地缓存或返回空数组。这个声明是纯配置不掺杂任何业务逻辑。Executor 层CLI 和 API 入口都指向同一个 Executor。它读取 Route 定义加载对应 Provider执行请求处理重试指数退避、超时可配置 per-route、熔断连续 3 次 5xx 自动熔断 60 秒、日志结构化 JSON含 request_id、provider、route_name、status_code、duration_ms。你通过 CLI 执行agent-reach run --route youtube-title-summary --input {video_id:dQw4w9WgXcQ}背后走的就是这套完整流水线。这种设计带来的根本性改变是业务逻辑和基础设施逻辑彻底分离。产品经理改需求只需修改 Route 文件里的endpoint或query参数运维同学查问题直接 grep 日志里的route_name和request_id安全团队审计只需检查 Provider 配置里凭据是否加密存储、是否启用最小权限原则。我不再需要教新人“怎么写一个健壮的 API 调用”只需要教他“怎么写一个正确的 Route 定义”。2.2 为什么选择 CLI 作为主入口而不是 Web UI 或 SDK网络热词里 “cli” 出现频率远高于 “web ui” 或 “sdk”这绝非偶然。在我经手的 23 个 AI 工具项目中有 19 个的初始验证阶段都是靠 CLI 完成的。原因很实在零依赖启动一个curl命令就能触发完整链路。curl -X POST http://localhost:8000/api/v1/run -H Content-Type: application/json -d {route: reddit-trend, input: {subreddit: machinelearning}}。不需要打开浏览器、不需要安装插件、不需要配置 IDE。对于数据科学家、运营同学、甚至客户成功经理这是最低门槛的交互方式。可脚本化集成CLI 输出是标准 JSON可直接被 Bash、Python、Airflow、GitHub Actions 消费。我们给客户部署时交付物就是一个agent-reach.yaml配置文件 一组.route.yaml文件 一个deploy.sh脚本。客户运维同学复制粘贴三行命令整个 API 中枢就跑起来了不需要理解 Node.js 或 Python 语法。调试即所见agent-reach debug --route youtube-search --verbose会输出完整的请求头、请求体、响应头、响应体、耗时、重试次数。没有黑盒没有隐藏逻辑。当我第一次看到它把 DeepSeek 的400 context length exceeded错误自动关联到 Route 里配置的max_tokens: 8192参数并提示“当前输入 token 估算值为 10240请调整 input 或增加 max_tokens”我就确信这是真正为工程师设计的工具。Web UI 固然友好但它天然带来状态管理复杂度、权限控制开销、前端构建维护成本SDK 虽然灵活但意味着每个语言都要维护一套且版本同步永远是个噩梦。CLI 是 Unix 哲学的终极体现做一件事并把它做好。Agent-Reach 的 CLI 不是“附加工具”它是整个系统能力的镜像——你能在 CLI 里做的API 就能做API 能做的CLI 也支持。二者共享同一套 Router、Executor、Provider 核心只是入口不同。2.3 Route 设计的精妙之处如何用声明式语法覆盖 95% 的 API 场景一个典型的.route.yaml文件长这样name: reddit-submission-summary description: 获取 Reddit 帖子的标题、文本摘要和热度评分 provider: reddit method: GET endpoint: /r/{subreddit}/hot params: limit: 10 t: day path_params: subreddit: {{ input.subreddit }} query_params: show: all headers: User-Agent: {{ env.USER_AGENT }} body: null response_schema: type: array items: type: object properties: title: type: string minLength: 1 selftext: type: string score: type: integer minimum: 0 timeout_ms: 5000 retry_policy: max_attempts: 3 backoff_factor: 2 jitter: true retry_on: - status_code: 429 - status_code: 503 - network_error: true fallback: type: static value: []这个看似简单的 YAML背后是大量工程权衡。我来拆解几个关键设计点动态参数注入{{ input.subreddit }}和{{ env.USER_AGENT }}不是模板字符串而是 Jinja2 引擎的安全沙箱执行。它禁止任意代码执行只允许白名单内的函数如urlencode,base64encode。这意味着你可以安全地把用户输入如 subreddit 名注入到 path 中而不用担心路径遍历攻击。对比传统脚本里fhttps://api.reddit.com/r/{subreddit}/hot的写法这里天然免疫注入漏洞。响应 Schema 驱动校验response_schema不是装饰性的注释而是运行时强制校验。如果 Reddit API 返回的score字段是字符串123而非整数123Executor 会捕获ValidationError记录详细错误位置/items/0/score: expected integer, got string并触发 fallback。这避免了下游业务代码因字段类型不符而崩溃。我们在一个金融舆情项目中就靠这个功能提前发现 Reddit 数据源变更——他们悄悄把score从 int 改成了 float我们的 Route 在上线前就报错而不是等到生产环境数据错乱。智能重试策略retry_on明确列出哪些错误码或条件触发重试。429和503是经典重试候选但network_error: true很关键——它捕获 DNS 解析失败、连接超时等底层错误这些在传统脚本里往往被忽略或误判为业务错误。backoff_factor: 2表示每次重试间隔翻倍1s, 2s, 4sjitter: true加入随机抖动±100ms防止大量请求在同一时刻重试导致雪崩。这比手写time.sleep(2**attempt)严谨得多。Fallback 机制type: static只是其中一种。还有type: route调用另一个 Route 作为备选、type: cache返回 Redis 缓存、type: error抛出自定义错误。在一个电商比价场景中我们配置拼多多 API 失败时 fallback 到淘宝 API再失败则 fallback 到静态历史均价——保证业务连续性而不是简单报错。这个设计的威力在于95% 的 API 交互都可以用这种声明式语法覆盖。无论是 RESTful 的 CRUD还是 GraphQL 的 query/mutation或是 WebSocket 的订阅只要能抽象出“输入 - 请求 - 响应 - 校验”这个范式就能用 Route 描述。它不追求语法糖的炫技而是用最朴实的 YAML解决最普遍的工程痛点。3. 核心细节解析与实操要点Provider、Route、Executor 如何协同工作3.1 Provider 注册与配置如何让 YouTube 和 Reddit “和平共处”在一个系统里Provider 是 Agent-Reach 的基石它的质量直接决定整个系统的稳定性。我见过太多项目因为 Provider 实现粗糙导致整个链路不可靠。Agent-Reach 的 Provider 设计有三个硬性要求认证隔离每个 Provider 必须有自己的凭据管理模块绝不共享全局变量。YouTube Provider 使用google-auth库处理 OAuth2凭据存储在~/.agent-reach/youtube/credentials.jsonReddit Provider 使用praw库凭据存在~/.agent-reach/reddit/config.iniDeepSeek Provider 则只读取DEEPSEEK_API_KEY环境变量。它们之间物理隔离互不影响。错误码标准化不同服务商的错误码五花八门。YouTube 返回403 forbidden表示 quota 超限Reddit 返回403 forbidden可能是 bannedDeepSeek 返回401 unauthorized表示 key 无效。Provider 必须将这些原始错误码映射到 Agent-Reach 统一的StandardErrorType枚举AUTH_ERROR: 认证失败key 无效、token 过期、scope 不足RATE_LIMIT_ERROR: 配额/限流429、quotaExceededVALIDATION_ERROR: 请求参数错误400、badRequestSERVICE_UNAVAILABLE: 服务不可用503、upstream timeoutNETWORK_ERROR: 网络层错误DNS fail、connection refused这样Executor 的重试策略、告警规则、日志分类都基于统一错误类型而不是去 parse 每个服务商的 response body。健康检查接口每个 Provider 必须实现health_check()方法返回{ status: ok | degraded | down, details: {...} }。Agent-Reach 启动时会并发调用所有 Provider 的健康检查并在/healthAPI 返回聚合结果。我们在一个项目中就靠这个功能提前发现 YouTube API 的 region endpoint 切换——健康检查返回degraded并提示region changed from us-central1 to us-west1运维同学立刻切换配置避免了业务中断。实操中注册一个新 Provider 的步骤极其简单创建providers/myapi/__init__.py继承BaseProvider类实现get_client()方法返回封装好的 HTTP 客户端推荐httpx.AsyncClient实现health_check()方法在providers/__init__.py中导入并注册编写config/providers/myapi.yaml定义默认配置base_url, timeout, etc.。整个过程不超过 50 行代码。我们曾用 2 小时就为一个内部 CRM 系统编写了专属 Provider接入了它的 REST API。关键是这个 Provider 一旦注册就自动获得所有 Agent-Reach 的基础设施能力重试、熔断、日志、监控。你不用再为每个新 API 重复造轮子。提示Provider 的凭据绝不硬编码Agent-Reach 默认支持四种凭据源环境变量MYAPI_KEY、配置文件config/providers/myapi.yaml、密钥管理服务AWS Secrets Manager、HashiCorp Vault、以及运行时注入CLI--env参数。生产环境强烈推荐使用密钥管理服务开发环境可用配置文件但必须 gitignore。3.2 Route 的生命周期管理从定义、测试到上线如何保证零故障Route 不是写完就扔的配置文件而是一个有生命周期的“软件资产”。Agent-Reach 内置了一套完整的 Route 管理流程定义Define用 YAML 编写.route.yaml放在routes/目录下。支持目录嵌套如routes/social/reddit/、routes/video/youtube/便于组织。验证Validateagent-reach validate --route reddit-trend会静态检查 YAML 语法、schema 是否符合规范、引用的 Provider 是否存在、response_schema是否合法 JSON Schema。这一步在 CI/CD 中强制执行杜绝语法错误上线。测试Testagent-reach test --route reddit-trend --fixture test_data/reddit-hot.json。Fixture 是预定义的 mock 响应用于单元测试。Agent-Reach 会启动一个 mock server拦截所有对 Reddit API 的请求返回 fixture 数据。测试覆盖率要求100% 的response_schema路径必须有对应 fixture所有retry_policy的分支必须被触发。我们用这个功能在一个 Reddit 数据项目中提前发现了tweek参数在某些 subreddit 下返回空数组的边界 case。调试Debugagent-reach debug --route youtube-search --input {q:AI tools} --verbose。这是最常用的命令。它会显示解析后的最终 URLhttps://www.googleapis.com/youtube/v3/search?qAItoolspartsnippettypevideomaxResults25实际发送的 headers含 Authorization请求耗时、重试次数响应 status code、headers、body截断显示避免刷屏Schema 校验结果✓ items[0].snippet.title: string部署Deployagent-reach deploy --env prod --routes routes/social/。它会将指定目录下的所有 Route连同其依赖的 Provider 配置打包成一个routes-bundle.tar.gz上传到目标服务器的/opt/agent-reach/routes/并触发 reload。整个过程原子化失败则回滚到上一版本。这个流程的价值在于把 Route 从“配置”提升为“可测试、可版本化、可审计的代码”。每个 Route 都有 Git commit history每次变更都有测试报告每次上线都有部署日志。当业务方说“昨天还好的今天突然不行了”运维同学可以直接git diff查看 Route 变更git blame定位责任人而不是在服务器上盲猜。注意Route 的name字段是全局唯一标识符也是 API 路径的一部分/api/v1/run?route{name}。命名必须遵循kebab-case小写字母短横线禁止空格、下划线、大写字母。我们曾因一个 Route 命名为youtubeSearch导致 API 调用GET /api/v1/run?routeyoutubeSearch404因为 Agent-Reach 内部路由匹配是严格 kebab-case 的。教训命名即契约必须规范。3.3 Executor 的执行引擎一次run命令背后发生了什么当你执行agent-reach run --route reddit-hot --input {subreddit:python}Executor 会按以下精确顺序执行路由解析Routing根据route名称从routes/目录加载对应的 YAML 文件解析成内存对象。同时从config/providers/加载redditProvider 配置。输入预处理Input Processing将--inputJSON 字符串解析为 Python dict。然后应用 Jinja2 模板引擎渲染path_params、query_params、headers中的所有{{ }}表达式。例如subreddit: {{ input.subreddit }}渲染为subreddit: python。凭据加载Credential Loading调用 Reddit Provider 的凭据加载器按优先级顺序查找环境变量 配置文件 密钥管理服务。加载成功后注入到 HTTP client 的auth或headers中。请求构建Request Building根据method、endpoint、path_params、query_params、headers、body构建最终的 HTTP 请求对象。URL 被规范化去除多余斜杠、编码特殊字符。健康检查Health Check调用 Reddit Provider 的health_check()。如果返回status: down直接跳过请求进入 fallback 流程。请求执行Execution使用httpx.AsyncClient发送异步请求。设置timeouttimeout_ms并启用limits连接池大小、最大重定向数。响应处理Response Handling如果状态码在200-299进入校验流程如果状态码在retry_on列表中且max_attempts未用尽则等待backoff_factor ** attempt * jitter时间后重试如果状态码是4xx且不在retry_on中根据StandardErrorType映射记录错误类型如果是5xx或网络错误同样触发重试或错误处理。Schema 校验Schema Validation使用jsonschema库对响应 body 执行response_schema校验。任何不匹配都会抛出ValidationError并记录详细路径。日志记录Logging生成结构化日志包含{ event: route_execution, route_name: reddit-hot, provider: reddit, status: success, status_code: 200, duration_ms: 428.3, retries: 0, request_id: a1b2c3d4-e5f6-7890-g1h2-i3j4k5l6m7n8, input_hash: sha256:abc123..., output_size_bytes: 12456 }这些日志被发送到 stdout供 CLI 查看和 configured logger如 file、syslog、ELK。结果返回Result Return将校验通过的响应 body序列化为 JSON输出到 stdoutCLI或 HTTP response bodyAPI。整个流程是高度可插拔的。你可以替换httpx为aiohttp可以自定义日志格式可以添加 pre-execution hook如记录审计日志可以添加 post-execution hook如触发 Slack 通知。但默认行为已经足够健壮覆盖了 99% 的场景。4. 实操过程与核心环节实现从零开始搭建一个 YouTube Reddit 联合分析工作流4.1 环境准备与安装为什么推荐 Docker Compose 而非 pip installAgent-Reach 的官方安装方式是pip install agent-reach但在生产环境中我强烈推荐使用 Docker Compose。原因有三依赖隔离Agent-Reach 依赖httpx,jinja2,pydantic,jsonschema等库而你的项目可能依赖不同版本。Docker 容器确保 Agent-Reach 运行在纯净、锁定的依赖环境中避免ImportError或AttributeError。配置即代码docker-compose.yml文件本身就是一份可执行的部署文档。它清晰定义了Agent-Reach 服务的镜像、端口、环境变量Redis用于缓存和熔断状态PostgreSQL用于持久化执行日志和 Route 版本Nginx作为反向代理提供 HTTPS 和基本认证一键启停docker-compose up -d启动docker-compose down停止docker-compose logs -f查看日志。运维同学无需了解 Python、Node.js 或任何语言细节。一个最小可行的docker-compose.yml如下version: 3.8 services: agent-reach: image: ghcr.io/agent-reach/core:latest ports: - 8000:8000 environment: - AGENT_REACH_CONFIG_PATH/app/config - REDIS_URLredis://redis:6379/0 - DATABASE_URLpostgresql://agentreach:passwordpostgres:5432/agentreach - LOG_LEVELINFO volumes: - ./config:/app/config - ./routes:/app/routes depends_on: - redis - postgres restart: unless-stopped redis: image: redis:7-alpine command: redis-server --save 60 1 --loglevel warning volumes: - redis-data:/data healthcheck: test: [CMD, redis-cli, ping] interval: 10s timeout: 5s retries: 3 postgres: image: postgres:15-alpine environment: - POSTGRES_DBagentreach - POSTGRES_USERagentreach - POSTGRES_PASSWORDpassword volumes: - postgres-data:/var/lib/postgresql/data healthcheck: test: [CMD, pg_isready, -U, agentreach, -d, agentreach] interval: 30s timeout: 10s retries: 3 volumes: redis-data: postgres-data:注意volumes部分./config映射到容器内/app/config这是 Agent-Reach 查找providers/和config.yaml的位置./routes映射到/app/routes是 Route 文件的根目录。你只需在宿主机创建这两个目录放入配置和 Route 文件docker-compose up就能跑起来。实操心得首次启动时Agent-Reach 会自动初始化 PostgreSQL 数据库表结构routes,executions,providers。如果看到psql: error: connection to server at postgres (172.18.0.3), port 5432 failed: Connection refused别慌这是 Postgres 还没启动完。Docker Compose 的depends_on只保证启动顺序不保证服务就绪。正确做法是docker-compose up -d postgres等待docker-compose logs -f postgres显示database system is ready to accept connections再docker-compose up -d agent-reach。我们把这个检查步骤写进了wait-for-postgres.sh脚本集成在 CI/CD 中。4.2 配置 YouTube 和 Reddit Provider避开 OAuth2 和 rate limit 的深坑YouTube Provider 配置YouTube Data API v3 的认证是 OAuth2这是最易出错的环节。Agent-Reach 的 YouTube Provider 已内置完整流程你只需提供client_secret.json。在 Google Cloud Console 创建新项目启用 YouTube Data API v3。创建 OAuth2 凭据选择“桌面应用”下载client_secret.json。将client_secret.json放入config/providers/youtube/目录。创建config/providers/youtube.yaml# config/providers/youtube.yaml base_url: https://www.googleapis.com/youtube/v3 default_timeout_ms: 10000 scopes: - https://www.googleapis.com/auth/youtube.readonly cache_dir: ~/.agent-reach/youtube/cache # 这里不配置 credentials_fileAgent-Reach 会自动查找 client_secret.jsonAgent-Reach 第一次运行时会检测到client_secret.json并启动本地 HTTP serverhttp://localhost:8080引导你完成 OAuth2 授权流程生成credentials.json并存入~/.agent-reach/youtube/。之后所有请求都自动使用这个 token并在过期时静默刷新。关键避坑不要手动编辑credentials.json它包含refresh_token是长期有效的。如果误删需要重新走 OAuth2 流程。我们有个客户运维同学以为这是普通配置定期清理~/.agent-reach目录结果导致所有 YouTube Route 失效。解决方案在docker-compose.yml中将~/.agent-reach/youtube映射为一个持久化 volume避免容器重启丢失。Reddit Provider 配置Reddit 的认证相对简单但user_agent是生死线。Reddit API 明确要求每个请求必须携带User-Agentheader且格式为platform:app_name:version (by /u/username)。如果缺失或格式错误直接 403。在 Reddit App Preferences 创建一个 “script” 类型应用获取client_id和client_secret。创建config/providers/reddit.yaml# config/providers/reddit.yaml base_url: https://oauth.reddit.com default_timeout_ms: 5000 client_id: your_client_id_here client_secret: your_client_secret_here username: your_reddit_username password: your_reddit_password # 仅用于 initial auth, not stored user_agent: linux:agent-reach:v1.0 (by /u/your_reddit_username) # 注意user_agent 必须包含 /u/username且不能是 generic 字符串Agent-Reach 会使用client_id、client_secret、username、password获取 access_token并缓存到 Redis 中。后续请求都使用这个 token无需每次都登录。关键避坑user_agent字符串中的your_reddit_username必须是你在 Reddit 上的真实用户名且必须是/u/开头。我们曾用your_reddit_username占位结果所有请求 403。Reddit 的错误响应是{error: invalid_user_agent}非常隐晦。解决方案在config/providers/reddit.yaml中用 Jinja2 模板user_agent: linux:agent-reach:v1.0 (by /u/{{ env.REDDIT_USERNAME }})然后通过docker-compose的environment注入REDDIT_USERNAME。4.3 编写联合分析 Route如何让 YouTube 和 Reddit 的数据在同一个工作流里流转现在我们来创建一个真正的业务价值分析某个技术话题如 “ComfyUI”在 YouTube 和 Reddit 上的热度趋势并生成摘要报告。这个工作流需要两个 Route 协同youtube-topic-search搜索 YouTube 上关于 “ComfyUI” 的视频返回标题、描述、观看数、上传时间。reddit-topic-search搜索 Reddit 上关于 “ComfyUI” 的帖子返回标题、文本、分数、评论数。topic-comparison-report接收两个 Route 的输出进行合并、去重、排序生成 Markdown 报告。首先创建routes/video/youtube-topic-search.route.yamlname: youtube-topic-search description: 搜索 YouTube 上指定话题的视频 provider: youtube method: GET endpoint: /search params: part: snippet q: {{ input.topic }} type: video maxResults: 25 order: viewCount publishedAfter: {{ input.since_date }} headers: Authorization: Bearer {{ provider.access_token }} response_schema: type: object properties: items: type: array items: type: object properties: snippet: type: object properties: title: type: string minLength: 1 description: type: string publishedAt: type: string format: date-time channelTitle: type: string required: [items] timeout_ms: 15000 retry_policy: max_attempts: 2 backoff_factor: 2 fallback: type: static value: { items: [] }然后创建routes/social/reddit-topic-search.route.yamlname: reddit-topic-search description: 搜索 Reddit 上指定话题的帖子 provider: reddit method: GET endpoint: /search params: q: {{ input.topic }} sort: relevance t: all limit: 100 headers: User-Agent: {{ env.REDDIT_USER_AGENT }} response_schema: type: object properties: data: type: object properties: children: type: array items: type: object properties: data: type: object properties: title: type: string minLength: 1 selftext: type: string score: type: integer minimum: 0 num_comments: type: integer minimum: 0 created_utc: type: number required: [data] timeout_ms: 10000 retry_policy: max_attempts: 3 backoff_factor: 2 retry_on: - status_code: 429 - network_error: true fallback: type: static value: { data: { children: [] } }最后创建routes/analysis/topic-comparison-report.route.yaml。这是一个特殊的 Route它的provider是builtin表示不调用外部 API而是执行内置的 Python 函数name: topic-comparison-report description: 合并 YouTube 和 Reddit 数据生成热度分析报告 provider: builtin method: POST endpoint: /report body: | {% set youtube_data input.youtube_data %} {% set reddit_data input.reddit_data %} {% set topic input.topic %} {% set combined [] %} {% for item in youtube_data.items %} {% set clean_title item.snippet.title | replace(ComfyUI, ) | trim %} {% set entry { source: YouTube, title: item.snippet.title, summary: item.snippet.description[:200] ~ ..., score: item.snippet.viewCount | int, date: item.snippet.publishedAt[:10], url: https://youtu.be/ ~ item.id.videoId } %} {% do combined.append
阅读完成 · 觉得有帮助?
咨询建站