拓冰建站拓冰建站
首页 / 资讯中心 / 正文

AI 软件开发实战教程(十一):让系统找到可能同路的人

“AI 软件开发实战教程”系列第 11 篇不用模糊推荐分数先把同路候选写成可以解释、可以反证、不会重复的业务规则再用两个浏览器用户验证异步匹配。上一篇把微信群中的“车找人”和“人找车”变成了结构化信息。但两条信息即使已经同时存在也不会自动认识彼此。例如车主早上发布明早 8:05万科悦城到软件新城2 个座位乘客可能隔几个小时才发布明早 8 点左右万科悦城到软件新城群聊里较早的消息早已被刷走。邻行 K3 要做的是在第二条信息出现时重新检查已经存在的另一类信息为双方形成一个“可能同路”的候选。这里最容易犯的错误是一上来就设计一个看似聪明的匹配分数。首版数据少、地点粗、真实反馈也不足一个 87 分的结果既难解释也不能证明比明确规则更有用。先写“不匹配”的条件与其问“怎样算很像”不如先问“什么情况下绝对不能形成候选”。邻行把必要条件写成一组全部都要满足的判断同一个社区 一条车找人一条人找车 不是同一个发布者 同一个出行日期 两条信息都仍然有效 双方匹配截止时间都还没到 车主仍至少有一个座位 可出发时间窗口存在交集 起点和终点相同或命中管理员配置的路线兼容规则其中任何一项失败结果就是“不形成候选”而不是降低几分后仍勉强推荐。这样的规则对早期产品有两个好处用户能理解为什么看到这条信息开发者也能为每个反例写出确定测试。用纯规则把反例固定下来K3 仍从红灯开始。第一批测试导入尚不存在的apps.matching测试收集阶段就失败证明代码库确实没有这项能力。随后建立evaluate_pair。它接收车主信息、乘客信息和明确的当前时刻返回是否兼容、规则版本和结构化解释不负责发送提醒。参数化测试逐个破坏必要条件把乘客改成同一个发布者把日期推迟一天把时间窗口错开三小时把信息状态改为关闭把匹配截止移到过去使用没有兼容关系的地点。每个变化都必须得到空结果。正例则检查解释中保存了日期相同、时间重合和路线依据。纯规则的意义不只是代码好测。它迫使产品语言也保持克制系统知道“大范围路线和时间可能合适”不知道双方具体在哪个门上车更不知道最后是否真的约定成功。路线兼容为什么必须有版本起点和终点完全相同时邻行使用内置规则版本 1。社区管理员还可以维护显式兼容关系例如车主万科悦城 → 软件新城 乘客悦城北门 → 中软 解释大范围路线兼容 规则版本3候选会保存当时使用的版本和解释而不是每次打开页面重新计算最新说法。如果管理员以后发现这条关系不合适并发布版本 4旧候选仍能说明自己为什么在版本 3 下产生新计算则使用新规则。否则一次规则修改可能让历史页面突然换理由排查投诉时也找不到当时事实。兼容关系是有方向的。司机路线和乘客路线分别存储不能默认反过来也成立更不能把“附近”扩张成不受控的自由文本。候选唯一不能只靠代码先查一次发布服务在新信息保存后触发候选重算。它会扫描同社区、相反类型的有效信息再交给纯规则判断。但“先查询没有再创建”挡不住两个请求同时发生。数据库因此对下面的组合建立唯一约束车主信息 乘客信息 规则版本重算服务仍使用幂等的get_or_create数据库约束负责最后防线。测试连续重算两次最终只能得到1 个候选 1 个业务事件 双方各 1 条站内提醒这比要求消息队列“保证只执行一次”更现实。任务可以重试业务结果仍然稳定。一件事不等于一条通知记录一个新候选对双方来说是同一件业务事实但两个人的提醒结果可能不同。因此数据分为三层Candidate └── BusinessEventcandidate.created ├── 车主的站内提醒 渠道投递记录 └── 乘客的站内提醒 渠道投递记录业务事件用稳定键保证同一候选只创建一次。每个接收者都有自己的站内提醒和渠道状态待发送、成功、失败、结果未知或未启用。K3 只创建这些持久化事实不在发布请求里直接访问喵提醒。这样第三方变慢不会拖住发布事务也不会因为其中一个人的喵码无效而抹掉另一个人的站内提醒。没有启用外部渠道时投递记录明确标为“未启用”站内提醒仍然存在。自动测试专门断言了这个降级路径。需要诚实说明的是本节点还没有证明喵提醒真正发送成功。实际 Worker、错误分类、每小时上限和摘要属于 K7。现在通过的是事件与独立投递事实不是外部送达。候选页面为什么不能写“匹配成功”用户在页面上看到的是可能同路不是已确认同行 日期相同 时间窗口有交集 起终点相同 / 命中某条兼容规则 具体上下车位置仍需双方通过微信确认页面没有匹配百分比也不说系统已经替双方达成约定。候选列表和详情只对两个参与者开放。其他登录成员即使猜到链接也得到 404。页面此时不加载任何微信号或喵码因为“可能同路”还不构成披露联系方式的授权。这条边界也为下一节点留下清晰起点只有参与者主动确认交换后系统才同时向双方披露微信号。用两个浏览器验证异步出现单个浏览器无法证明双方看到的是同一个结果。K3 的 Playwright 测试创建两个完全隔离的浏览器上下文分别保存自己的登录会话移动视口都是 375×812。测试流程是车主登录并发布 → 乘客登录并发布 → 第二次发布触发候选重算 → 车主进入候选列表和详情 → 乘客进入候选列表和详情 → 双方都看到“可能同路”和相同的微信确认提示它验证了用户不必同时在线也不必重新发送群消息。较早发布的人在后来者出现后仍能获得站内结果。浏览器测试没有伪造复制微信或真实外部提醒那些能力尚未实现。它只证明当前页面、会话隔离、发布触发和双方授权组成的纵向流程。本节点怎样验收K3 收口时得到76 个非浏览器测试通过分支覆盖率 90.74%Ruff、格式、mypy strict、迁移和 Django 检查通过V0 到 K3 共 4 条 Chromium 用户旅程通过精确路线和版本化配置路线均有可解释正例日期、时间、状态、截止和同用户等反例不会形成候选重复重算不增加候选、事件或站内提醒无外部渠道时双方站内提醒仍存在WebKit、PostgreSQL、微信真机和外部实际发送仍未被宣称通过结果只形成本地提交不推送。验收矩阵中AC-14 至 AC-17 可以自动通过。AC-18 和 AC-54 只能标为部分通过因为本节点证明了事件和双方独立记录却还没有执行 K7 的真实发送。AC-55 也只能部分通过无渠道降级已经证明一方失败不影响另一方仍待故障测试。写在最后匹配系统的第一版不需要显得聪明需要显得可信。明确必要条件、保存当时解释、用数据库保证唯一、把一个业务事实拆成双方独立通知结果这些基础会让后续功能更容易演进。等真实试用产生足够反馈再讨论扩大路线兼容、排序或推荐才有数据可以判断改动是否真的更好。下一篇进入 K4当一方决定联系候选时怎样再次检查权限和时效在一个事务中同时向双方披露微信号保存不会随资料修改而变化的加密快照并让复制失败时仍可手动选择。关键代码与操作下面的简化测试把“形成一个候选”继续展开为解释、事件和双方提醒数量deftest_matching_pair_creates_explainable_candidate(driver_trip,passenger_trip):candidatesrecompute_candidates_for_trip(trippassenger_trip,nowtimezone.now(),)assertlen(candidates)1assertcandidates[0].explanation{date:same,time:overlap,route:exact,}assertBusinessEvent.objects.count()1assertInAppNotification.objects.count()2验证命令make bugfix TESTtests/matching/test_candidate_matching.py::test_matching_pair_creates_one_explainable_candidate_and_two_notifications候选、解释和通知必须在同一条测试里对齐否则页面可能显示一个无法追溯来源的结果。本篇验证摘要候选只在同社区、角色互补、时间重叠且路线兼容时形成路线规则带版本历史候选保留当时使用的解释不被后续配置改写数据库唯一约束和稳定事件键避免重复候选与重复提醒双方分别得到站内提醒和独立投递记录一方失败不会回滚另一方候选页面只展示形成原因和随机短编号不提前披露联系方式。附录相关工具与仓库gstack仓库garrytan/gstack地址https://github.com/garrytan/gstackdev-harness仓库Dev-Wiki/dev-harness地址https://github.com/Dev-Wiki/dev-harnessUI UX Pro Max Skill仓库nextlevelbuilder/ui-ux-pro-max-skill地址https://github.com/nextlevelbuilder/ui-ux-pro-max-skill
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门