⚽ 对话式开发 · 技术实践
和 AI 聊了几周,他把世界杯实时应用做了出来
一位开发者通过纯对话式开发,用几周时间与 Cortex Code Desktop(CoCo)合作,构建了一款 2026 世界杯实时应用——48 支球队、16 个场馆、实时比分、AI 预测与淘汰赛对阵,全程几乎零手写脚手架。
综合公开信息整理•
全文约 4 分钟读完
#对话式开发
#Cortex Code
#Streamlit
#Snowflake
#世界杯应用
💬 纯对话
几乎每个功能都由自然语言生成
48 队
覆盖全部参赛球队与 FIFA 排名
10s
实时比分区域刷新频率
⚡ 30 秒速览
- 不是小 demo:首页从 4 张静态指标卡起步,逐步迭代出实时比分、动画统计、淘汰赛对阵、AI 预测标签、冠军庆祝彩带。
- 真实性够硬:ESPN 未公开 API 的坑被逐一踩平——约 100 场结果截断、跨午夜丢比赛、9 种比赛状态枚举。
- 实时不靠 WebSocket:@st.fragment 10 秒局部刷新 + 15 秒 TTL 缓存,把 API 压力压到最低。
- 预测是双层的:统计评分(35/20/15/15/15 权重)+ Snowflake Cortex AI 十五词一句话推理。
- 一个诚实的注脚:作者自己列了四个改进方向,明确承认这套架构并不完美。
01发生了什么 一个“聊”出来的实时应用
先说结论:这个应用没有样板代码,没有脚手架,几乎每个功能都是靠和 Cortex Code Desktop(CoCo)自然语言对话,一问一答迭代出来的。
但“对话式开发”不等于“随便说说”。
从拿到空白仓库,到最终可实时打开的世界杯应用,作者用了几周——时间主要花在把新想法、新交互和更多实时数据不断「聊」进产品里。首页的演进最能说明问题:
🏠 首页 dashboard:从 4 张静态卡片到实时直播台
- 起步:4 张指标卡(距开赛天数、剩余场次、48 支球队、16 个场馆)+ 一张赛程表。
- 第一次进化:实时比赛卡、动画统计 pills(控球率 / 射门 / 角球)、进球 / 黄牌 / 红牌事件标记。
- 第二次进化:下一场比赛的 JS 倒计时;多场同开时自动堆叠卡片。
- 第三次进化:纵向淘汰赛 bracket,叠加金色 AI 预测徽章。
- 最终形态:实时胜率条、带赛事统计摘要的球队卡片、决赛结束后的冠军庆祝卡与 confetti 动效。
全部通过和 CoCo 的对话完成。其他四个页面——Head-to-Head、Venue Map、Knockout Bracket、Quiz——走的是同一条路。
02它能做什么 一个可以实时打开的世界杯中心
这不是概念演示,而是一个部署在 Streamlit Community Cloud 上的真实应用。静态赛事数据存在 Snowflake,实时数据来自 ESPN,AI 预测来自 Snowflake Cortex。
🏠
首页实时中心
比分、事件、动画统计、倒计时、胜率条一屏聚合
📊
Head-to-Head 交锋
球队历史对阵数据对照
🗺️
Venue Map 场馆图
16 个世界杯场馆的定位与容量信息
🧮
Knockout Bracket
纵向淘汰赛对阵,点击选择晋级球队,已定赛果自动锁定
🤖
AI 预测
金色徽章显示预测胜率,另附一句 AI 推理说明
注:以上功能均基于真实赛事数据进行渲染,实时部分随比赛进程滚动更新,非静态截图。
03为什么可信 真实 API 的三个坑,一个都没躲掉
你可能会想:对话生成的 App,是不是只是把组件拼在了一起?
但真实世界的 API,不会为 demo 让路。
ESPN 提供了一个公开但未文档化的免费接口,实时比分全从这来。作者在里面踩了典型的四个坑,并且都给出了工程解法:
坑 1约 100 场赛事截断
查询整个赛事周期日期范围时,ESPN 会把结果静默截断在约 100 场——半决赛结果直接「消失」,直到赛事中段才发现。
解法:把查询拆成两个日期区间,分别拉取。
坑 2跨午夜丢比赛
不传日期参数时,ESPN 只返回美东时间当日数据。一场 23:55 开球、午夜后仍处于补时的比赛,会在跨天后直接从结果里消失。
解法:始终查询一个前后 3 天的窗口。
坑 39 种状态,漏一个就崩
ESPN 用 6 种进行中状态 + 3 种结束状态描述比赛。只要漏掉其中任何一个,淘汰赛 bracket 就会出乱子。
解法:全部枚举、逐条映射。
坑 4CDN 偶发空响应
ESPN 偶尔会因 CDN 抖动返回空结果,导致页面闪烁。
解法:把最近一次有效 live 数据缓存在 st.session_state 中,请求失败则回退到上一份可用数据。
04不靠 WebSocket,也能做到接近实时
这个应用没有用 WebSocket。它的实时性来自 Streamlit 的 @st.fragment 装饰器——按固定间隔只重跑被装饰的函数,而不触发整页刷新。
ESPN API(无认证)→
@st.cache_data ttl=15s→
@st.fragment 局部刷新→
浏览器实时渲染
10s
实时比赛区域刷新
60s
赛程 / 结果区刷新
60s
页面顶部 banner 刷新
注:st.fragment 只重跑被装饰的函数,配合 API 调用的 15 秒 TTL 缓存,能以极低的外部 API 负载维持接近实时的推送体验。
05预测引擎:两层结构,快慢结合
整个预测系统分成两层。第一层是确定性统计评分——基于真实赛事表现换算综合评分,快、免费、不需要调 API;第二层是 Cortex AI 推理——负责解释「为什么这么预测」。
第一层 · 统计评分公式
五项指标归一化后加权求和
35
20
15
15
15
胜率
场均净胜球
场均控球率
场均射正
零封率
通过对比双方评分换算出胜率百分比,完全基于确定性计算,毫秒级返回。
第二层 · Cortex 推理
把两队完整赛事统计送入模型,要求用一句话、不超过 15 个词给出预测并点出关键差异。
SNOWFLAKE.CORTEX.AI_COMPLETE
实时胜率修正
比赛进行中,根据实时赛况动态计算:每个进球约 +18 个百分点,红牌约 -15,控球与射正微调 ±5~8。
每 10s 与比分同步更新
06一个诚实的注脚 作者自己列的四条改进清单
这篇分享最难得的地方,是作者在结尾主动列出了自己认为还不完美的地方——没有把项目包装成「最佳实践」。
- API 调用太脆:直接依赖未公开文档的接口,未来会考虑通过 Snowflake External Function 代理,增加降级与重试机制。
- 复杂交互靠取巧:淘汰赛 bracket 里的 JavaScript 与 Streamlit 只能通过 window.parent DOM 操作通信,更干净的方案是自定义双向 Streamlit Component。
- 预测缓存不聪明:5 分钟 TTL 意味着比赛刚结束、下一轮预测不会立即更新;基于赛果数量生成 Hash 的失效策略会更好,但做不到完全实时。
- 代码永远可以重构:一个应用,永远都还有继续重构的空间。
注:这份清单的价值在于——它把「对话式开发的不完美」也如实摊开了,而不是只展示高光。
编辑核心判断
对话式开发的真正突破,不是替代工程师,而是把「工程」下放成了「对话」。
当脚手架、部署、API、UI 都能用自然语言重构,软件生产的门槛正从「会写代码」变成「会描述问题」。但排障的过程——理解状态、缓存、边界条件——仍然属于人类。能精准描述问题的人,反而更稀缺了。
▶自己动手
原帖附有在线应用体验地址与 GitHub 源码,可在 macOS 与 Windows 上安装 Cortex Code Desktop,把一个想法「聊」成应用。
从一句自然语言开始 →
「git push 即上线」——Streamlit Community Cloud 监听仓库,几秒内自动重新部署,无需 Docker 与 CI/CD。