
高考成绩查询时间、批次录取安排、征集志愿节点、体检和面试要求这些信息分散在各省教育考试院官网、招生简章、官方公众号和各类新闻页面里。家长和考生往往要跨多个网站反复刷新仍然担心错过关键节点。“高考智能助手 API”要解决的问题就是把这些分散的进度信息汇聚成一个统一入口用户只提一个问题API 返回汇总后的进度、状态和官方来源链接让信息可查、可追溯、可核对。这篇文章会围绕这样一个聚合型 API 的设计过程展开先定义数据模型再搭建一个 FastAPI 最小服务实现“查询进度 汇总官方来源”的核心接口然后用 curl 验证结果最后整理常见 API 报错和生产化要点。它适合正在做信息聚合类服务、政府公开数据对接、或想学习如何把“多源数据”封装成统一接口的开发者。1. 先把问题定义清楚高考智能助手 API 到底聚合什么1.1 信息分散的本质不是“网站多”而是“没有统一模型”表面上看高考信息分散是因为渠道多省级教育考试院官网、招生考试信息平台、官方公众号、招考电台、新闻客户端甚至学校内部通知。但真正让开发者和用户都头疼的是这些渠道背后的数据没有统一模型。同一个省份成绩查询公告可能是一篇网页志愿填报安排可能是一张图片附件分数线发布可能是一条公众号推送。不同省份之间字段命名、发布时间粒度、事件分类也完全不同。有的省份按“批次”组织信息有的省份按“日程”组织有的省份只发一条总公告。这带来两个后果用户侧不知道去哪里找也不知道哪个来源最权威容易把第三方平台的预测信息当成官方安排。开发侧如果想做一个查询工具必须针对每个省份写一套解析逻辑后续维护成本极高。所以聚合的第一步不是写爬虫而是先抽象出一套统一的数据模型。只要每个事件都能落到“省份 事件类型 状态 计划时间 官方来源”这个结构里查询、汇总、订阅提醒就都顺了。1.2 智能助手 API 的职责边界高考智能助手 API 的定位不是替代官方渠道而是做“信息聚合层”和“查询网关”。它要做的事情有四件收集从各省官方渠道获取招生考试公告、进度通知和时间安排。标准化把不同格式的信息转成统一结构补上省份、事件类型、计划时间、来源 URL。存储保存最新状态同时保留历史变更记录方便追溯。提供查询接口让小程序、网页、聊天机器人等客户端通过一个接口拿到汇总结果和官方链接。边界也要明确这类 API 不应发布预测分数线不应替用户做志愿决策不应制造“非官方渠道提前出分”的错觉。它只负责把官方信息聚合、翻译成统一结构并引导用户回到官方来源核对。1.3 本文的技术主线后面的内容按一条主线推进数据模型设计 - 种子数据准备 - FastAPI 项目搭建 - 查询接口与汇总接口实现 - curl 验证 - 常见 API 报错排查 - 生产环境要点 - 扩展方向。每一步都尽量给出可运行的最小示例。实际工程里数据采集可能来自定时任务、管理后台录入或第三方数据交换但对外暴露的统一查询接口设计思路是一致的。2. 数据模型设计一条公告记录需要哪些字段2.1 从一条公告倒推字段设计数据模型时不要从数据库表开始而是先从一条真实的公告开始。假设用户在“某省教育考试院”看到一篇标题为《2025年普通高考成绩查询时间和录取控制分数线公布安排》的通知里面包含发布机构发布时间成绩查询开始时间分数线发布时间官方原文链接咨询电话把这句话转成结构化记录最低限度需要这些字段唯一 ID、省份编码、省份名称、事件类型、事件名称、当前阶段、计划时间、状态、来源名称、来源 URL、发布时间、更新时间、标签。计划时间和状态要分成两个字段这是一个容易踩坑的地方。很多聚合服务只存“时间”等官方发通知说“成绩公布推迟两天”时就把时间改了但用户无法判断改之前是什么。保留状态字段待发布、已安排、已发布、已结束、已取消并用 updated_at 记录变更时间才能回答“这个进度到底更新过没有”。2.2 事件类型、状态和省份编码要枚举化事件类型不要自由填写否则会出现“成绩发布”和“出分时间”其实是同一件事但查不出来。建议先维护一套可扩展的枚举枚举值含义典型公告score_release成绩发布高考成绩查询时间及方式line_release分数线发布录取控制分数线公布volunteer_fill志愿填报本科、专科志愿填报时间安排admission_batch批次录取提前批、本科批、专科批录取时间collection_volunteer征集志愿征集志愿时间和缺额计划recheck成绩复核成绩复核申请时间与流程physical_check体检体检时间安排interview面试军校、警校、特殊类型招生面试省份编码建议直接使用国家标准行政区划代码比如北京 110000、上海 310000、江苏 320000、广东 440000、四川 510000。这样后续对接行政区划统计、地图展示、区域筛选都很方便。状态字段建议使用pending未到时间、scheduled已安排、published已发布、closed已结束、canceled已取消。注意 scheduled 和 published 的区别scheduled 表示官方已经预告了时间但正文还未发布published 表示正式公告已经发出这个字段直接决定用户看到的文案。2.3 用一份种子 JSON 验证模型数据模型写完之后先用一份种子数据跑通流程再考虑真实爬虫。下面是开发阶段可以放入 data/seed.json 的示例省份名称和链接用于演示正式环境必须替换成官方真实公告并逐条核对链接。[ { id: BJ-2025-0001, province_code: 110000, province_name: 北京市, event_type: score_release, event_name: 2025年普通高考成绩查询与录取控制分数线公布, stage: 成绩查询, planned_time: 2025-06-25, status: published, tags: [成绩查询, 分数线], source_name: 北京教育考试院示例, source_url: https://www.example.edu.cn/bjeea/gkcj, published_at: 2025-06-25T10:00:0008:00, updated_at: 2025-06-25T10:30:0008:00 }, { id: BJ-2025-0002, province_code: 110000, province_name: 北京市, event_type: volunteer_fill, event_name: 2025年本科批次志愿填报时间安排, stage: 志愿填报, planned_time: 2025-06-27, status: scheduled, tags: [志愿填报, 本科], source_name: 北京教育考试院示例, source_url: https://www.example.edu.cn/bjeea/zybf, published_at: null, updated_at: 2025-06-01T09:00:0008:00 } ]这段示例的用意是验证两点第一JSON 能不能完整表达一条公告第二查询接口能不能按省份、事件类型、状态过滤出结果。种子数据不需要很多覆盖两三个省份、三四种事件类型就够了。2.4 来源字段是“可核对”的关键任何聚合类服务都必须保留 source_name 和 source_url。用户看到“成绩 6 月 25 日公布”之后需要能点开官方原文确认这比任何缓存和推送都可靠。实际项目里建议再加一个 source_checked_at 字段记录这个来源最近一次被巡检确认的时间。如果某个官方链接已经失效接口返回时应该把对应条目标记为“来源待确认”不要继续把过期链接当有效信息展示。3. 环境准备与最小项目骨架3.1 为什么示例选 FastAPI聚合查询接口的核心诉求是快速开发、清晰定义请求参数和响应结构、自动生成接口文档。示例选择 Python FastAPI因为它用类型注解就能声明参数自带 Swagger 文档代码量小适合演示概念。选型没有绝对标准下面表格给出常见选择技术栈优点适合场景Python FastAPI开发快、类型提示强、文档自动生成原型验证、数据聚合服务、AI 接口封装Java Spring Boot生态成熟、团队招聘容易、运维规范已有 Java 技术栈的中大型团队Node.js Express/Nest前后端语言统一、异步性能好前端团队主导的 BFF 服务如果团队已经有稳定的技术栈完全可以用 Spring Boot 或 NestJS 实现同样的接口下面的数据结构、参数校验和响应设计思路可以直接迁移。3.2 创建虚拟环境并安装依赖本地建议使用虚拟环境避免污染系统 Python。Windows 和 macOS/Linux 命令略有不同python -m venv venv source venv/bin/activate # Windows PowerShell: venv\Scripts\Activate.ps1 # Windows CMD: venv\Scripts\activate.bat激活后安装 FastAPI 和 uvicornpip install fastapi uvicorn pydantic安装完成后可以检查版本确认环境没有缺包python -c import fastapi; print(fastapi.__version__)如果这一步报 ModuleNotFoundError说明当前 shell 激活的虚拟环境不对或 pip 安装到了全局环境。先执行which pythonWindows 是where python确认路径。3.3 项目目录结构最小项目建议按下面结构组织gaokao-assistant-api/ ├── app/ │ ├── __init__.py │ ├── main.py # FastAPI 应用与接口 │ └── data.py # 种子数据加载 ├── data/ │ └── seed.json # 开发用种子数据 ├── requirements.txt └── README.md这是我推荐的目录结构因为数据文件和代码分离后面换成 MySQL、PostgreSQL 或 MongoDB 时只需要改 data.py 的读取逻辑接口层不用动。正式项目还可以加 schemas、services、crawlers 等目录但最小验证阶段不需要。3.4 先启动一个空服务在 app/main.py 写入最简应用from fastapi import FastAPI app FastAPI(title高考智能助手 API, version0.1.0) app.get(/health) def health(): return {status: ok}启动服务uvicorn app.main:app --host 127.0.0.1 --port 8000 --reload浏览器打开 http://127.0.0.1:8000/docs 可以看到自动生成的接口文档访问 http://127.0.0.1:8000/health 应返回{status:ok}。这一步的检查点有两个一是服务能启动二是文档页能打开。如果端口被占用可以换--port 8001如果app.main:app提示找不到应用说明当前目录不在项目根目录uprocin 需要从包含 app 包的目录运行。4. 核心接口实现一次请求返回进度汇总和官方来源4.1 查询接口 /v1/query 的参数设计查询接口要做到“一次请求结果可筛选、可排序、可分页”。参数设计如下参数类型必填说明province_codestring否省份行政区划代码如 110000event_typestring否事件类型枚举值statusstring否状态枚举值keywordstring否标题和标签模糊搜索关键字start_datestring否计划时间范围起始格式 YYYY-MM-DDend_datestring否计划时间范围结束pageint否页码从 1 开始默认 1page_sizeint否每页条数默认 20最大 100页码和每页条数必须设置边界。很多调用方会把 page 传成 0 或负数或者把 page_size 传成 10000这会造成数据库压力。FastAPI 的 Query 类型可以直接限制取值范围。4.2 参数校验要放在过滤之前参数校验必须放在业务逻辑之前。否则一个错误参数会一直穿透到数据库层最后抛出一个含义不明的数据库异常。from typing import Optional from fastapi import FastAPI, HTTPException, Query app FastAPI(title高考智能助手 API, version0.1.0) EVENT_TYPES { score_release: 成绩发布, line_release: 分数线发布, volunteer_fill: 志愿填报, admission_batch: 批次录取, collection_volunteer: 征集志愿, recheck: 成绩复核, physical_check: 体检, interview: 面试, } STATUS_VALUES {pending, scheduled, published, closed, canceled}app.get(/v1/query) def query_announcements( province_code: Optional[str] None, event_type: Optional[str] None, status: Optional[str] None, keyword: Optional[str] None, start_date: Optional[str] None, end_date: Optional[str] None, page: int Query(1, ge1, description页码从 1 开始), page_size: int Query(20, ge1, le100, description每页条数), ): if event_type and event_type not in EVENT_TYPES: raise HTTPException( status_code400, detailfevent_type 不合法可选值: {sorted(EVENT_TYPES)}, ) if status and status not in STATUS_VALUES: raise HTTPException( status_code400, detailfstatus 不合法可选值: {sorted(STATUS_VALUES)}, ) if start_date and end_date and start_date end_date: raise HTTPException(status_code400, detailstart_date 不能晚于 end_date) # 过滤逻辑写在这里 return {query: ok}这里的关键点是event_type 和 status 使用了“白名单校验”而不是“黑名单过滤”。接口能接受哪些值由后端控制调用方传错立即得到明确提示而不是返回空列表让调用方猜原因。日期范围校验也很有必要否则用户传了 start_date 大于 end_date 时查询会静默返回空结果很难排查。4.3 过滤、排序和分页逻辑为了让接口真正可用需要把种子数据加载到内存再实现过滤逻辑。先用 data.py 加载 JSONimport json from pathlib import Path _SEED_PATH Path(__file__).resolve().parent.parent / data / seed.json def load_seed_data(): with open(_SEED_PATH, r, encodingutf-8) as f: return json.load(f)然后在查询接口里完成过滤。演示环境用内存列表就够了生产环境换成数据库查询时只需要把过滤条件翻译成 SQL 或 ORM 表达式。from .data import load_seed_data ANNOUNCEMENTS load_seed_data() app.get(/v1/query) def query_announcements( province_code: Optional[str] None, event_type: Optional[str] None, status: Optional[str] None, keyword: Optional[str] None, start_date: Optional[str] None, end_date: Optional[str] None, page: int Query(1, ge1), page_size: int Query(20, ge1, le100), ): if event_type and event_type not in EVENT_TYPES: raise HTTPException(status_code400, detailfevent_type 不合法可选值: {sorted(EVENT_TYPES)}) if status and status not in STATUS_VALUES: raise HTTPException(status_code400, detailfstatus 不合法可选值: {sorted(STATUS_VALUES)}) if start_date and end_date and start_date end_date: raise HTTPException(status_code400, detailstart_date 不能晚于 end_date) result ANNOUNCEMENTS if province_code: result [a for a in result if a[province_code] province_code] if event_type: result [a for a in result if a[event_type] event_type] if status: result [a for a in result if a[status] status] if keyword: result [ a for a in result if keyword in a[event_name] or any(keyword in t for t in a[tags]) ] if start_date: result [a for a in result if (a.get(planned_time) or ) start_date] if end_date: result [a for a in result if (a.get(planned_time) or ) end_date] result.sort(keylambda a: a[planned_time] or 9999-12-31) total len(result) start (page - 1) * page_size items result[start:start page_size] return { total: total, page: page, page_size: page_size, items: items, official_sources: [ {source_name: a[source_name], source_url: a[source_url]} for a in items ], }排序逻辑这里按 planned_time 升序没有计划时间的记录排到最后。空字符串排序容易出错所以用or 9999-12-31兜底。这个细节在实际项目中经常被忽略会导致没有日期的记录排在前面。4.4 汇总接口 /v1/summary把结果变成一段人话只返回结构化列表用户还要自己判断“现在到哪一步了”。可以再加一个汇总接口输入一个省份输出一段自然语言进度说明同时附上官方来源列表。这就是“一个问题汇总进度与官方来源”的核心体验。请求体用 Pydantic 模型声明from pydantic import BaseModel from typing import Optional class SummaryRequest(BaseModel): province_code: str event_type: Optional[str] None question: str 接口实现app.post(/v1/summary) def get_summary(req: SummaryRequest): matched [a for a in ANNOUNCEMENTS if a[province_code] req.province_code] if req.event_type: if req.event_type not in EVENT_TYPES: raise HTTPException(status_code400, detailfevent_type 不合法可选值: {sorted(EVENT_TYPES)}) matched [a for a in matched if a[event_type] req.event_type] if not matched: return { summary: 暂未收录该查询条件对应的官方进度信息请以当地教育考试院最新公告为准。, items: [], official_sources: [], } matched.sort(keylambda a: a[planned_time] or 9999-12-31) lines [f{matched[0][province_name]}已汇总 {len(matched)} 条官方进度信息] for idx, a in enumerate(matched, start1): time_str a.get(planned_time) or 时间待定 lines.append(f{idx}. {a[event_name]}{EVENT_TYPES.get(a[event_type], a[event_type])}计划时间 {time_str}状态 {a[status]}。) summary \n.join(lines) return { summary: summary, items: matched, official_sources: [ {source_name: a[source_name], source_url: a[source_url]} for a in matched ], }question 字段在这里先保留不做实际处理。后续接入大模型后question 可以驱动“智能问答”逻辑包括时间限定、省份限定和结果提炼。这样接口协议稳定升级时客户端不需要改代码。4.5 响应字段约定聚合类接口的响应建议统一为下面结构字段类型说明totalint满足条件的总数pageint当前页码page_sizeint每页条数itemsarray公告记录数组official_sourcesarray官方来源摘要包含 source_name 和 source_urlsummarystring仅汇总接口返回的自然语言说明官方来源不放在 items 里嵌套太深而是单独返回列表方便客户端直接渲染“信息来源”区域。这个结构简单前端和小程序都能直接使用。5. 运行验证用 curl 确认接口行为5.1 准备种子数据并启动把上一节的代码整理好确保 data/seed.json 存在然后启动服务uvicorn app.main:app --host 127.0.0.1 --port 8000 --reload看到Uvicorn running on http://127.0.0.1:8000说明启动成功。接着用 curl 验证。5.2 验证单省份查询curl http://127.0.0.1:8000/v1/query?province_code110000预期响应中 total 等于该省份的种子数据条数每条记录包含省份、事件类型、计划时间、来源 URL。也可以组合过滤条件curl http://127.0.0.1:8000/v1/query?province_code110000event_typescore_releasestatuspublished这个请求只返回“北京市 成绩发布 已发布”的记录。如果返回空列表先检查 seed.json 里是否真的存在满足条件的记录再检查参数拼写是否正确。5.3 验证汇总接口curl -X POST http://127.0.0.1:8000/v1/summary \ -H Content-Type: application/json \ -d {province_code: 110000, question: 北京什么时候出成绩}预期返回一段自然语言汇总以及对应的 official_sources 数组。前端拿到这段 summary 可以直接展示在页面上用户不必自己扒表格。5.4 验证异常分支curl http://127.0.0.1:8000/v1/query?event_typenot_exist预期返回 HTTP 400{ detail: event_type 不合法可选值: [admission_batch, collection_volunteer, interview, line_release, physical_check, recheck, score_release, volunteer_fill] }异常分支验证是接口测试里最容易漏掉的部分。只验证正常路径的接口会在联调阶段被调用方各种奇怪参数打回来建议把参数校验的每条分支都测一遍。注意不要只验证服务能启动还要验证输入、输出、异常分支和日志是否符合预期。接口文档可以自动生成但参数边界和错误信息需要手动设计。6. 常见 API 报错排查速查聚合服务上线后最常见的不是业务逻辑问题而是 API 调用链路上的报错。下面按错误码整理一套排查顺序。错误现象常见原因检查方式处理建议400 the thinking_budget parameter must be a positive integer参数类型或取值范围不对查看接口文档中该参数约束按文档传正整数不要传字符串或 0400 this models maximum context length is 1048576 tokens请求内容超过模型上下文上限检查 prompt 和返回内容长度缩短输入、做摘要或使用分段处理400 model name 不被支持模型名写错或已下线对比服务商最新模型列表更新 model 字段到当前可用值401 login failed / token 校验失败Token 过期、权限范围不对检查 token 生成时间和 scope重新生成 token确认权限范围402 insufficient balance账户余额不足登录控制台查余额充值或切换额度更合适的模型403 http 403 / transport failure接口权限不足或未开通检查密钥权限、IP 白名单在控制台开通对应接口权限429 请求太频繁触发限流查看限流配置和响应头增加退避重试降低并发529 overloaded服务端临时过载查看服务状态页短暂等待后重试建议指数退避connection lost mid-response长连接中断、响应未完成查看客户端超时配置和日志设置合理 timeout实现断点续传或重试docker api npipe 连接失败Docker Desktop 未启动或内核未就绪执行 docker info重启 Docker Desktop等待引擎就绪6.1 400 参数错误先看字段名、类型和约束400 是所有 API 报错里信息量最大但最容易忽略的一类。报错信息往往直接告诉了你哪个参数不合法比如the thinking_budget parameter must be a positive integer说明必须传正整数又比如the supported api model names are ...说明 model 字段写错了。排查顺序是先确认字段名拼写再确认字段类型最后确认取值范围。不要一看到 400 就怀疑接口地址。很多大模型接口在版本更新后会调整参数名和模型名旧代码很容易触发这类错误。还有一类 400 跟上下文长度相关。报错信息里会出现maximum context length is ... tokens这是请求内容太长需要缩短 prompt 或对输入做截断、摘要处理。6.2 401 与 402认证失败和余额不足是两回事login failed. check api token or gitlab version这类报错常见于使用代码托管平台 API 时通常是 token 过期、token 权限不足或平台版本不匹配。处理方式是重新生成 token并检查 token 的 scope 是否包含所需 API 权限。402 insufficient balance则是账户余额问题。它会出现在大模型 API 调用里也会出现在任何按量计费的服务中。排查时登录控制台看余额和计费记录不要在后端反复重试同一个请求否则可能造成不必要的费用。6.3 429 与 529限流与过载要分开处理429 是客户端触发限流通常说明调用频率超过了配额。处理方式是降低并发、增加退避间隔并读取响应头里的 Retry-After 字段。529 是服务端过载报错原文经常是529 overloaded. this is a server-side issue, usually temporary。这不是客户端参数问题不要修改参数后立刻重试建议采用指数退避比如第一次等 1 秒、第二次等 2 秒、第三次等 4 秒。无论 429 还是 529重试都要有上限否则高峰期会把服务打得更满。生产环境建议用带最大重试次数的重试策略。6.4 连接中断与响应不完整api error: connection lost mid-response表示响应在传输中途断开调用方拿到的是不完整内容。常见原因包括客户端 timeout 设置过短、网络代理不稳定、服务端流式返回时间过长。排查时先看完整错误日志确认是建立连接超时、读取超时还是连接被重置。处理方式通常是调大 timeout、增加重试如果是流式接口还需要处理“已收到一半内容”的情况避免把截断内容当作完整结果写入数据库或展示给用户。6.5 403 权限不足与平台隐私限制transport failure for /api/agentpreset.list: http 403这类问题往往是调用方身份没问题但接口权限没有被授予。需要到控制台确认 API 权限、IP 白名单和密钥 scope。另一种 403 语义不同。小程序场景里常见的chooseImage:fail api scope is not declared in the privacy agreement或chooseLocation:fail api scope is not declared in the privacy agreement属于前端平台隐私政策问题需要在平台后台补充隐私声明而不是后端代码能解决的。遇到这类报错先确认报错来自后端接口还是前端小程序框架。6.6 一套可复用的排错顺序实际排错时按这个顺序走可以省掉很多无用功输入是否正确参数名、参数类型、必填项。文件和路径是否正确模块名、配置文件路径、读取的 JSON 是否存在。依赖版本是否匹配FastAPI、pydantic、第三方 SDK 版本。配置是否生效环境变量、密钥、开关。权限、端口、网络是否正常token、IP 白名单、端口占用。日志里的具体异常完整堆栈、响应体、耗时。平台或框架本身的限制限流、上下文长度、隐私声明、模型名称。7. 从演示到生产数据、缓存、日志和免责7.1 数据更新必须可追溯演示项目里数据是静态 JSON生产环境必须考虑更新链路。建议每条公告增加变更记录表至少记录 old_status、new_status、changed_at、change_source。这样当用户质疑“你这里说 6 月 25 日官方改成 6 月 26 日了”可以查清是什么时间、哪个来源、谁更新的。更新策略有三种选择定时巡检每天定时访问官方公告页比对标题和发布时间发现变化就更新记录。管理后台录入由运营人员手工维护关键节点适合数据量不大的场景。官方数据交换如果当地教育考试院提供开放数据接口优先对接官方接口比爬网页稳定得多。三种策略可以并存。服务端要做的是给每条数据打上来源标记和抓取时间不要无差别覆盖旧记录。7.2 加缓存和限流避免热点查询打满源站高考出分前后是流量高峰同一省份的查询会出现明显热点。缓存策略建议两级记录级缓存单条公告内容变化频率低可以设置 5 到 10 分钟 TTL。接口级缓存相同查询条件的响应可以直接返回缓存减少数据库和源站压力。限流也要区分用户。匿名用户的 QPS 限额可以低一些带有效 Key 的正式调用方可以高一些。限流不是针对爬虫而是保证高峰期间核心查询仍然可用。7.3 日志、监控和回滚生产环境至少要记录三类日志访问日志谁在什么时间调用了哪个接口返回状态码和耗时。数据更新日志哪些公告被新增、修改、下线。异常日志参数校验失败、来源请求失败、缓存穿透、数据库异常。监控指标建议关注接口 5xx 比例、平均响应时间、数据更新延迟、来源巡检失败次数。任何一个指标异常都应该有告警。发布新版本前保留上一版本的镜像或构建产物数据更新脚本也要考虑回滚比如某次抓取把公告错误标记为“已取消”要能快速恢复上一版数据。7.4 高考信息聚合服务的边界与纠错机制这类服务必须明确一个原则最终信息以官方发布为准。接口返回的 summary 和状态只能作为辅助不能替代官方公告。前端页面应当明显展示“数据来源为人工整理与网络巡检请以当地教育考试院官方公告为准”。同时要提供纠错入口。用户发现信息不一致时可以提交反馈运营人员核对官方公告后修改数据并记录变更。这个机制既是产品功能也是数据质量保障。8. 扩展方向大模型问答、订阅提醒和发布清单8.1 接入大模型做自然语言问答当前示例的 summary 是模板拼接扩展方向是接入大模型让用户直接问“北京本科批什么时候开始录取”得到更自然的回答。DeepSeek、讯飞星火、智谱等国内大模型 API 都提供了对话接口调用方式都是 POST 一个 JSON携带 model、messages、temperature 等参数。接入时要注意几个已有教训模型名容易写错接口会返回the supported api model names are ...这类提示开发时先复制文档里的完整模型名。部分模型开启思考模式后可能要求把上轮content[].thinking内容原样传回否则报错这个约束要在接入文档里单独确认。要把官方来源 URL 作为上下文传给模型并要求模型在回答末尾附上信息来源避免模型自由发挥。聚合