
AI-mediated product discoveryAI 中介产品发现指的是用户通过 AI 助手、智能客服或推荐机器人完成商品查找、筛选和决策的过程。这个过程和传统搜索框完全不同用户说出的是自然语言意图AI 必须把意图翻译成结构化查询再由商品目录服务端返回可解释的结果最后把用户点击、收藏、加购行为转换成反馈数据。实际项目中问题很快会出现不同平台的商品接口字段各不相同AI 无法统一处理搜索结果缺少解释用户不知道推荐依据反馈数据没有标准格式后续做排序优化无从下手。解决这些问题最直接的方式是设计一份开放协议让 AI 客户端、商品目录服务端和反馈收集端按照同一套数据契约通信。本文围绕这份协议的目标、数据模型、参考实现、验证方法和生产化改造展开读者可以把它当作协议草案或落地模板使用。1. 为什么 AI 中介产品发现需要一份开放协议1.1 交互链路变化从关键词搜索到意图翻译传统电商搜索的链路是用户在搜索框输入关键词搜索服务根据分词和倒排索引返回商品列表。用户自己负责把“想买什么”翻译成关键词搜索服务只做匹配。AI 中介模式下用户面对的是对话界面可能说“想找一台能写代码又不太重的笔记本”也可能说“预算五千左右平时带出门”。这些表达里没有商品的标准词AI 需要先做实体识别、意图理解和约束抽取再构造查询。链路从“关键词输入 - 列表返回”变成了“自然语言 - 结构化意图 - 商品匹配 - 推荐解释 - 行为反馈”。链路变长之后每一段都需要明确的数据契约。AI 客户端要知道自己该传什么商品服务端要知道自己该返回什么反馈系统要知道自己该采集什么。没有协议每个环节各自发明字段联调成本会迅速超过业务收益。1.2 直接调用商户接口的三个麻烦假设 AI 助手要接入多个商户的商品目录直接调用每个商户的 HTTP 接口会遇到三类问题。第一是字段语义不一致。一个商户用name表示商品标题另一个商户用title一个商户用price存带两位小数的数字另一个商户把价格放在skus[].salePrice字符串里。AI 端如果针对每家写适配代码每接入一家商户就多一套映射逻辑后期维护量非常大。第二是筛选逻辑无法统一表达。“不要太重”“预算五千左右”“要能跑大模型”这类描述在每个商户接口里都没有对应的参数。要么 AI 端把模糊条件拍平成关键词要么先拉回大量商品再做本地过滤两种做法都损失精度。第三是结果缺少解释。AI 推荐产品用户天然会问“为什么推荐这个”。普通商品接口返回的字段里没有推荐理由也没有匹配到用户哪个意图。AI 只能硬编解释或者干脆不解释。1.3 协议要解决的核心问题一份面向 AI 中介产品发现的开放协议至少要解决四个问题。第一统一请求结构。所有商户都按同一套 JSON 结构接收查询意图、约束条件、分页参数和会话上下文。第二统一响应结构。所有商户都返回商品 ID、标题、价格、属性、评分和推荐原因。第三统一反馈结构。点击、浏览、加购、拒收都能以标准事件形式回流。第四保留可扩展性。协议不规定每个语义槽的具体值而是用entities数组和attributes字典承载开放字段方便不同行业扩展。注意协议解决的是“各方如何沟通”不解决“算法怎么排序”。排序策略可以每个商户各自实现但排序结果必须放进统一的items和score字段里。这样 AI 端不用关心排序细节只消费标准结果。2. 协议分层四个职责必须分开设计协议时如果把会话、语义、结果、反馈全部混在一个 JSON 里后期维护会很痛苦。参考设计里把协议拆成四层。2.1 会话层身份与上下文会话层负责传递“谁在问、在什么场景问、有什么前置偏好”。字段包括sessionId、channel、locale、preferences。sessionId用于串联一轮对话中的多次查询。用户可能先问“轻薄本”再补充“预算 7000 以内”第二次请求带上同一个sessionId服务端就能理解这是对前一次结果的精化。preferences里放用户主动声明的品类、价格区间、币种等长期偏好。需要强调的是会话层只放用户授权提供的上下文不能偷偷采集行为数据。2.2 语义层意图、实体与约束语义层是协议的核心。AI 客户端负责把自然语言解析成结构化意图服务端负责消费这些结构化意图。intent.type表示查询类型常见取值有SEARCH、COMPARE、RECOMMEND、CLARIFY。entities数组里放识别出的实体每个实体包含类型、值和置信度。constraints数组里放过滤条件例如价格上限、重量上限、品牌白名单。这样设计的理由是职责分离AI 端只负责“理解用户”服务端只负责“匹配商品”。AI 不需要知道商品库怎么建索引服务端也不需要维护一套自然语言处理模型。2.3 结果层商品、评分与证据结果层用items数组承载返回商品每个商品必须包含productId、title、price、score和reasons。score是服务端排序得分AI 客户端可以用它做二次排序但不能只凭分数判断推荐质量。reasons是证据数组用结构化字段说明商品为什么被推荐例如匹配了哪个实体、满足了哪个约束。证据字段存在协议才能支持可解释推荐。2.4 交互层反馈、澄清与分页交互层负责一轮查询之外的行为。FeedbackEvent用于回流用户反馈clarification字段用于服务端在结果不确定时反向要求 AI 澄清pagination用于控制结果数量和翻页。分页参数虽然简单但在协议里必须明确定义offset和limit的语义。推荐场景里用户往往只关心前几条limit过大浪费带宽过小则无法覆盖多意图结果。3. 核心数据模型与 JSON 示例协议最终要落到数据结构上。下面以 JSON 格式给出三个核心模型的参考定义字段名采用小驼峰风格版本号统一放在protocolVersion。3.1 QueryRequestAI 客户端发什么一次查询请求至少包含请求 ID、意图、分页参数和可选会话上下文。{ protocolVersion: 1.0, requestId: req_20250101_001, session: { sessionId: sess_001, context: { channel: chat, locale: zh-CN }, preferences: { categories: [laptop], maxPrice: 8000.00, currency: CNY } }, intent: { type: SEARCH, queryText: 适合程序员写代码的轻薄本, entities: [ { type: CATEGORY, value: laptop, confidence: 0.92 }, { type: USE_SCENE, value: development, confidence: 0.85 } ], constraints: [ { field: weight_kg, operator: LE, value: 1.8 } ] }, pagination: { offset: 0, limit: 10 } }关键点在于entities和constraints是分开的。实体描述“用户提到了什么”约束描述“哪些条件必须满足”。同一句话可能同时包含两者但服务端处理逻辑不同实体影响召回和排序约束影响过滤。3.2 QueryResponse服务端回什么响应结构里status用统一错误码表示处理结果total表示匹配总量items是当前页商品pagination回应请求里的翻页参数。{ protocolVersion: 1.0, requestId: req_20250101_001, responseId: resp_001, status: { code: 0, message: OK }, total: 24, items: [ { productId: p_001, title: 示例轻薄本 Pro 14, description: 14 英寸 1.4kg 轻薄本适合日常开发和移动办公, price: 6999.00, currency: CNY, attributes: { weight_kg: 1.4, screen_size_inch: 14.0, cpu: R7-8845H }, score: 0.93, reasons: [ { type: INTENT_MATCH, description: 匹配用户提到的程序员开发场景 }, { type: PROPERTY_MATCH, description: 重量 1.4kg符合不超过 1.8kg 的条件 } ], url: https://example.com/p/001 } ], pagination: { offset: 0, limit: 10, hasMore: true } }reasons是响应的灵魂。如果服务端只返回商品不返回原因AI 端就无法向用户解释推荐依据整个协议就退化成普通商品接口。3.3 FeedbackEvent反馈如何回流反馈事件用于采集用户行为事件类型建议覆盖VIEW、CLICK、ADD_TO_CART、PURCHASE、REJECT。{ protocolVersion: 1.0, eventId: evt_001, sessionId: sess_001, requestId: req_20250101_001, type: CLICK, target: { productId: p_001 }, occurredAt: 2025-01-01T12:00:00Z, attributes: { position: 1 } }反馈事件必须带requestId否则无法还原“用户是在哪一次查询结果里点了这个商品”。productId要使用服务端返回的标准 ID不能用 AI 端自己拼接的临时 ID。occurredAt使用 ISO 8601 时间格式方便后续做时间窗分析。4. 最小可运行实现服务端与客户端光有数据结构还不够需要一套能跑起来的最小实现。下面用 Python 的 FastAPI 和 requests 搭建参考实现说明协议在实际代码里怎么落地。4.1 环境准备与依赖建议在独立虚拟环境中安装依赖。python -m venv .venv source .venv/bin/activate pip install fastapi uvicorn requests安装完成后把 FastAPI 应用写入main.py。这个文件同时承担路由定义、数据校验和示例商品匹配逻辑。4.2 服务端实现from typing import List, Optional from fastapi import FastAPI, HTTPException from pydantic import BaseModel app FastAPI(titleAI-Mediated Product Discovery Reference Server) class Pagination(BaseModel): offset: int 0 limit: int 10 class Intent(BaseModel): type: str SEARCH queryText: str entities: List[dict] [] constraints: List[dict] [] class QueryRequest(BaseModel): protocolVersion: str 1.0 requestId: str intent: Intent pagination: Pagination Pagination() class ProductItem(BaseModel): productId: str title: str description: str price: float currency: str CNY score: float 0.0 reasons: List[dict] [] class QueryResponse(BaseModel): protocolVersion: str 1.0 requestId: str responseId: str status: dict {code: 0, message: OK} total: int 0 items: List[ProductItem] [] pagination: dict {} _PRODUCTS [ {productId: p_001, title: 示例轻薄本 Pro 14, price: 6999.0, description: 14 英寸 1.4kg 轻薄本适合日常开发, category: laptop}, {productId: p_002, title: 示例全能本 16, price: 7999.0, description: 16 英寸大屏全能本适合重度开发, category: laptop}, {productId: p_003, title: 示例办公台式机, price: 4599.0, description: 标准办公配置适合日常办公, category: desktop}, ] app.post(/v1/discovery, response_modelQueryResponse) def discovery(req: QueryRequest): # 参考实现只做最简单的品类过滤和价格升序真实项目应接入搜索与排序服务 category laptop for ent in req.intent.entities: if ent.get(type) CATEGORY and value in ent: category ent[value] matched [p for p in _PRODUCTS if p[category] category] matched.sort(keylambda p: p[price]) start req.pagination.offset end start req.pagination.limit page matched[start:end] items [] for p in page: items.append(ProductItem( productIdp[productId], titlep[title], descriptionp[description], pricep[price], score0.9, reasons[{type: INTENT_MATCH, description: 匹配品类 laptop}] )) return QueryResponse( protocolVersion1.0, requestIdreq.requestId, responseIdresp_ req.requestId, totallen(matched), itemsitems, pagination{ offset: req.pagination.offset, limit: req.pagination.limit, hasMore: end len(matched) } )这段代码的核心是用 Pydantic 模型承担协议校验用POST /v1/discovery暴露发现接口用最小规则实现匹配和排序。真实项目里_PRODUCTS应该替换成商品数据库查询匹配逻辑应该替换成搜索引擎或向量召回。注意参考实现里score固定为 0.9只是为了验证响应结构。生产环境必须让score来自真实排序算法否则 AI 端拿到的评分没有任何区分度。4.3 客户端与 curl 验证客户端用 requests 构造协议请求。import requests payload { protocolVersion: 1.0, requestId: req_test_001, intent: { type: SEARCH, queryText: 程序员用的轻薄本, entities: [{type: CATEGORY, value: laptop, confidence: 0.92}] }, pagination: {offset: 0, limit: 5} } resp requests.post(http://127.0.0.1:8000/v1/discovery, jsonpayload) print(resp.status_code) data resp.json() for item in data[items]: print(item[productId], item[title], item[price], item[score])也可以直接用 curl 验证接口。curl -X POST http://127.0.0.1:8000/v1/discovery \ -H Content-Type: application/json \ -d {protocolVersion:1.0,requestId:req_01,intent:{queryText:轻薄本,entities:[{type:CATEGORY,value:laptop}]},pagination:{offset:0,limit:5}}启动服务后预期能看到三条 laptop 商品按价格升序返回total为 2hasMore为 false。如果请求里缺少requestIdPydantic 会返回 422这就是协议校验在起作用。5. 关键参数与语义对照协议参数看起来简单真正落地时每个字段都要明确语义否则两端经常出现“字段传了但没生效”的问题。5.1 参数速查表下面整理协议中出现频率最高的参数。字段含义推荐默认值调大或调小的影响pagination.limit单页返回商品数量10调大增加响应体积和延迟调小增加翻页次数对话场景建议 5 到 10pagination.offset翻页偏移量0过大时排序结果可能变化推荐场景慎用深翻页entity.confidence实体识别置信度0.8调高减少误匹配但降低召回调低更容易引入无关商品constraints.operator比较操作符EQ支持 GT、GE、LT、LE、IN错误运算符会导致过滤结果为空score服务端排序得分-只用于排序不建议直接展示给用户需要展示时应做归一化reasons[].type证据类型-建议使用枚举值避免 AI 端做无规则的文本解析5.2 匹配与排序的落地细节在参考实现里匹配只是简单的品类等值过滤。真实项目建议把匹配拆成三层硬过滤、软匹配、排序。硬过滤对应constraints例如价格上限、库存状态、发货地区。软匹配对应entities例如用户说“写代码”时商品标签里出现“开发”“编程”“程序员”都应该参与匹配。排序阶段再综合软匹配得分、用户偏好、商品热度和反馈转化率。需要特别注意conflict场景。如果用户说“预算五千左右”constraints里写了price LE 5000但商品库中最贴近的是 5299 元商品硬过滤会直接丢掉。处理方式有两种一是放宽约束后返回并标注approximate: true二是在响应里增加suggestion字段提示价格区间。协议设计建议把“放宽约束”作为可选能力由服务端在status里通过扩展字段说明。6. 运行验证从启动到结果分析6.1 启动步骤在虚拟环境中启动 FastAPI 服务。uvicorn main:app --host 127.0.0.1 --port 8000 --reload浏览器访问http://127.0.0.1:8000/docs可以看到 FastAPI 自动生成的接口文档这是验证字段结构最快的方式。也可以直接调用接口。6.2 预期输出正常响应应该满足以下检查点。status.code为 0。requestId与请求一致方便链路追踪。items中每个商品都有productId、title、price、score、reasons。total表示匹配总数pagination.hasMore与数据量一致。翻页第二页的offset为 10 时不会重复返回第一页商品。6.3 异常分支怎么测协议验证不能只测正常路径。建议至少构造以下异常场景。缺少requestId预期 422校验逻辑生效。pagination.limit传 0 或负数预期 422 或被服务端钳制为默认值。intent里没有entities预期返回全部品类商品或空列表取决于服务端策略。传入不存在的constraints.field服务端应明确报错而不是静默忽略。重复发送同一requestId如果是查询请求可以幂等返回如果是反馈事件服务端应去重避免统计翻倍。7. 常见问题与排查链路协议联调阶段最容易出问题的不是算法而是字段、编码、超时和数据一致性。下面按现象给出排查路径。问题现象可能原因检查方式处理建议请求返回 422必填字段缺失或类型不匹配查看响应里的详细校验错误对照协议 schema 修正请求体返回 404路由或前缀不一致检查客户端 URL 与服务端路由统一使用/v1/discovery中文乱码JSON 编码或 Content-Type 错误检查请求头是否包含application/json; charsetutf-8统一使用 UTF-8 编码结果为空过滤条件过严或实体识别错误打印服务端收到的entities和constraints先放宽过滤确认召回再逐步收紧所有商品评分相同排序逻辑未接入真实算法检查服务端计分代码引入属性匹配、热度、反馈信号翻页数据重复排序不稳定或 offset 使用错误对比两页的productId序列排序字段增加稳定 ID 辅助键反馈事件没生效requestId或productId不一致核对反馈事件与查询响应中的 ID反馈必须引用服务端标准 ID响应超时商品库查询过慢或召回范围过大查看服务端慢日志增加超时控制、限制召回上限排查顺序建议先看请求体是否通过校验再看服务端日志确认请求被正确解析然后核对过滤条件最后才怀疑排序和性能。很多“协议不工作”的问题实际是客户端把字段名拼错了。8. 从学习环境到生产环境8.1 开发环境怎么跑学习阶段只需要本地 FastAPI 服务和内存商品数组重点是把协议结构跑通理解每个字段在两个端之间怎么流动。可以故意构造几个错误请求观察 422 响应这比看文档更快掌握字段约束。开发环境可以增加一个 mock 客户端按脚本随机生成查询和反馈验证服务端对边界参数的容忍度。此阶段不建议引入复杂的排序模型先用规则排序保证结果确定方便对照。8.2 生产环境必须补的组件协议跑通只是第一步。生产环境至少要补齐以下能力。身份认证服务端要校验调用方身份至少使用 API Key敏感场景使用 OAuth2。限流与配额AI 客户端可能高频调用需要按租户设置 QPS 限制。超时与熔断单次查询设置 500ms 到 1s 超时超时后走兜底搜索。统一日志requestId贯穿网关、服务端、日志系统方便排查。敏感数据脱敏会话上下文里的用户偏好、经纬度、手机号等字段不能进原始日志。监控指标记录请求量、响应时间、召回量、空结果率、点击反馈延迟。灰度与回滚协议版本升级时新旧版本同时服务按protocolVersion路由到不同处理逻辑。学习环境和生产环境最大的差异是可靠性。内存数组可以丢关系库、缓存、索引、消息队列都要有备份和监控。协议本身不解决可靠性但协议的requestId和protocolVersion字段为灰度、链路追踪和回滚提供了基础。9. 最佳实践、检查清单与扩展方向9.1 可复用发布前检查清单无论协议是给内部 AI 助手用还是开放给第三方开发者发布前都要核对以下清单。协议版本号是否在请求和响应中都有是否使用语义化版本。必填字段是否清晰缺少字段时错误信息是否可读。枚举字段是否统一reasons[].type是否避免自由文本。分页逻辑是否确定排序是否有稳定键。反馈事件是否携带requestId和标准productId。超时、限流、认证、日志、监控是否配置完整。旧版本协议是否兼容升级策略是否明确。是否准备了 mock 数据或沙箱环境方便接入方自测。异常响应是否使用统一结构AI 端能否通过status.code区分参数错误和内部错误。隐私相关字段是否在接口文档里标注用途和保留周期。9.2 扩展方向从单目录到联邦目录当前协议假设 AI 客户端对接一个商品目录服务端。实际场景里一个 AI 助手可能要同时查询多个商户或者一个城市的多个门店这就引出联邦目录方向。联邦目录下协议需要增加requestDistribution和mergeStrategy字段。requestDistribution让服务端把同一查询分发到多个子目录mergeStrategy定义结果如何合并可以按价格区间分区也可以按商户信用分加权。反馈层还要把merchantId加入target否则无法定位到具体来源。另一个值得做的方向是流式结果。当商品库很大时AI 端希望服务端先返回前几条高置信结果再逐步补充减少用户等待。此时可以把协议扩展为 SSE 或 WebSocket 通道QueryResponse的items分成多个分片推送status标记完成状态。最后是评估体系建设。协议标准化之后可以用统一结构采集查询日志和反馈事件离线计算召回率、精确率在线用点击率、转化率验证排序策略。没有评估体系的协议只能算是接口规范有了评估体系才能持续优化推荐质量。整体来看AI 中介产品发现的价值在于把自然语言理解、商品检索、可解释推荐和反馈闭环串在一起。协议的价值在于让每一段链路都清晰可控。先跑通最小闭环再逐步加入联邦目录、流式响应和自动评估这是在真实业务里落地这套协议最稳妥的路径。