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

AI宠物功能落地复盘:从大模型API到多模态识别的工程实践

上个月我们团队做了一次比较完整的AI功能落地在现有App里增加了一个“AI宠物”模块从产品定义、技术选型、接口联调到上线灰度走完一整轮。这篇文章是对这个项目从头到尾的复盘重点是那些文档里不会写、只有真正联调才会遇到的决策和问题。如果你也在考虑给App接入大模型能力或者想做一个带“养成”和“陪伴”属性的AI功能这篇复盘应该能帮你省掉不少弯路。1. 为什么是“宠物”以及这个功能最终被定义成什么样1.1 产品背景留存的压力与AI能力的选择先说背景。我们有款面向年轻用户的生活记录类App内容以任务打卡和日常记录为主功能本身没有太大问题但用户完成核心任务之后基本就走缺乏回访理由。月中的一次数据复盘次留和30日留存都出现小幅下滑产品经理提了一个需求能不能用AI做一个有“粘性”的功能让用户有理由每天打开App当时团队手里可选的AI方向有几种AI总结报告、AI内容生成、AI拍照识别、AI对话陪伴。内部讨论最久的是“AI总结”因为它和App原本的记录属性契合做成每周报告、每月报告看起来顺理成章。但最后我们放弃了原因很直接总结类功能打开频率太低一周一次已经算高撑不起“每天打开”的目标。真正让我们决定做“宠物”的是数据里一个细节App里图片上传功能的使用频次很高用户特别喜欢晒自己的猫和狗。我们连续翻了几天用户上传内容的标签统计宠物相关内容占据图片量的将近三分之一。既然用户已经在App里晒宠物那就顺势做一个“AI宠物”功能用户领养一只数字宠物既能当聊天陪伴又能拍照识别现实里的猫狗顺便把记忆和提醒功能揉进去。1.2 定义功能边界AI宠物不只是聊天机器人立项之后的第一件事不是写代码而是把“AI宠物”这个模糊概念切成具体功能。我们最后定义了四条主线领养与形象用户进入宠物模块后从几个品种中选一只给宠物起名字设置生日和性格标签。对话陪伴宠物具备独立的性格能陪用户聊天并根据用户心情调整语气和回应方式。拍照识别用户拍下自家猫狗的照片宠物能认出来这是什么品种、大概多大、今天看起来心情如何并给出一些趣味性的解读。记忆与提醒宠物能记住用户告诉它的关键信息比如宠物名字、生日、疫苗时间、某个习惯并在合适的时候主动提醒。同时我们也明确了一版不做的事不做虚拟形象生成不做复杂养成数值喂食、升级、对战不做用户之间的宠物社交。原因很简单一个星期内我们不可能把养成系统做得比运营两年多的养成类产品更好那就不如把有限的资源集中在AI能力本身上让用户先被“对话真、识别准、记得住”打动。边界明确之后整个功能就有了一个很清晰的最小闭环用户领养一只宠物和它聊几句拍一张自己宠物的照片然后第二天再回来看看宠物还记不记得昨晚聊了什么。1.3 三个核心场景的优先级排序功能切完之后还要排优先级不然开发过程中一定会被无限加需求。我们的排列逻辑是先做能验证核心假设的场景再做差异化场景。P0文本对话陪伴、宠物档案、基础记忆。这是整个功能的底座没有对话和记忆其他都无从谈起。P1拍照识别、主动提醒。拍照识别是差异化亮点主动提醒是提升回访频次的钩子。P2语音输入、养成扩展。放到版本迭代里再说。回头看这个排序是值得的。因为AI项目的最大风险根本不是“模型效果不好”而是“功能太多导致链路不稳定最后连一个场景都没跑通”。P0目标只有一个让用户觉得宠物真的在和他建立关系。这个目标一旦成立P1和P2才有意义。2. 整体架构与选型Agent、大模型API与端侧怎么分工2.1 功能链路拆解从App触摸到模型返回先给整体架构画一个轮廓方便后面每个模块的展开。客户端是Flutter双端后端是Python FastAPI服务模型能力全部通过云端API调用数据层使用PostgreSQL加向量扩展。用户从App里打开宠物页面看到一只宠物形象点击聊天输入框输入一句话请求进入后端会话服务。会话服务负责几个事情读取用户身份和宠物档案把最近的对话历史整理成上下文补充长期记忆检索结果然后组装成请求发给大模型API。大模型返回文本后会话服务再把回复文本持久化同时把可提取的事实性信息交给记忆服务做异步抽取最终把回复推回App。图片识别走的是另一条链路App上传图片后端先做图片预处理和基础分类判断再调用多模态大模型的视觉接口把识别结果转成结构化JSON返回给前端展示同时也把识别记录存储到记忆表里。这个链路里最关键的取舍是我们选择让后端做所有的模型编排客户端只做展示和交互。原因是多端复用和权限控制后续如果我们要在微信小程序、网页端加同一个人宠物入口后端一套服务就能覆盖不需要每个端各写一套接模型API的逻辑。2.2 大模型选型为什么不微调只做编排模型选型时团队内部讨论最多的是“要不要微调一个垂直宠物模型”。我当时的态度非常明确不微调。理由有三个。第一数据量不够。我们手里真正的宠物对话数据几乎没有如果要从零开始整理对话微调数据没有几万条高质量样本很难见效这个成本远远超过模型本身的API费用。第二效果天花板。通用大模型已经具备相当强的宠物知识储备和对话能力通过合理的系统提示词和检索增强已经能做出“懂宠物”的体验而微调模型一旦训不好可能连基础对话能力都会下降。第三迭代速度。我们用的是大模型API模型厂商每次升级底座我们的效果都能跟着提升不需要自己维护训练链路。对一个小型团队来说这几乎是最优选择。实际开发中我们使用了大模型API的文本对话接口主要做休闲陪伴和记忆问答同时使用同一个厂商的多模态视觉接口处理宠物图片识别。一个额外的好处是同一个厂商的接口鉴权、配额和计费模型是统一的省去对接多套SDK的麻烦。提示如果你对大模型API不熟悉只要记住一句判断标准——你手里有没有别人拿不到、而且量大到能改变模型输出的数据如果没有就不要自己做微调。先把检索增强和提示词工程做到位往往性价比更高。2.3 多模态识别与宠物状态管理宠物识别模块最初被一些人质疑“这个功能直接调图像分类模型不就行了”但实际上真实用户拍的宠物照片非常复杂涉及光线、角度、遮挡、模糊、多只宠物同框等情况单一分类模型很难覆盖。我们选择的方案是分成两层。第一层是前置规则判断。图片上传后先做尺寸压缩、格式校验用轻量分类模型判断“图里到底是不是宠物”以及“大致是猫还是狗”。如果图片里没有人脸、车牌等敏感信息我们就可以放心进入下一步如果图像质量太差直接返回提示让用户重新拍。第二层是调用多模态大模型的视觉接口让它输出结构化的识别结果。这里有个很关键的操作不能让它随便返回一段文字而是要求返回JSON结构包含品种、置信度、年龄区间、情绪、显著特征、健康备注。后续前端直接渲染JSON不需要做文本解析更稳定。宠物状态管理则放在会话服务里用一个独立的“宠物状态表”存储。状态字段包括心情、活跃度、最近互动时间、累计聊天次数等。每次对话结束后根据用户输入的情绪和内容状态值会做一点偏移。比如用户说“今天加班好累”宠物状态里的“安慰指数”就增加回复也会更温和用户表达开心宠物状态就偏向兴奋回应会更调皮。状态管理最大的作用是让宠物看起来“有情绪”而不是一个永远同一语气的ChatBot。这个功能并不复杂但非常有效用户感知特别明显。2.4 记忆存储长期记忆的落库方案宠物的记忆是整个功能里最容易被低估的部分。对话历史本身需要短期记忆但宠物还需要跨会话记住用户告诉过它的“事实”。我们把它拆成两层。短期记忆存储在会话服务的内存缓存里默认保留最近20轮对话。达到20轮之后超过部分会被异步压缩成一条摘要存进数据库同时从短期缓存里淘汰。这样的话用户隔天回来继续聊宠物还能接上之前的语境。长期记忆使用PostgreSQL加pgvector扩展来实现向量检索。数据库里专门建了记忆事件表每条记录包含宠物ID、用户ID、事件类型、标题、详细描述、时间等字段同时用文本嵌入模型生成对应的向量存在pgvector字段里。当用户问宠物“你记得我上周跟你说我家的猫生病了吗”系统先把问题转成向量按相似度从记忆表里取回Top5再把这些记忆拼接进大模型请求的上下文。为什么不单独用向量数据库当时评估过Milvus和专门的向量库产品但我们的数据量不到百万级别PostgreSQL加pgvector完全扛得住而且能和业务表放在同一个事务里不用处理双写的一致性问题运维成本也低。等以后数据量真的大了再迁移也不迟。3. 核心实现从Prompt到Agent再到App接入3.1 让宠物“像宠物”人格化System Prompt的写法模型选好之后所有“宠物感”都来自系统提示词。这一块我们迭代了很多版本我自己最大的体会是一个人格化Prompt的关键不是堆形容词而是把“视角限制”和“行为规则”写清楚。先看一个当时比较成熟的System Prompt骨架内容已脱敏处理你是{宠物姓名}一只{月龄}个月大的{品种}现在生活在你主人的手机里。 初始性格标签{性格列表比如粘人、傲娇、好奇心强} 你的能力边界 - 你能陪主人聊天、安慰主人、分享铲屎官日常。 - 你不知道你是一个模型也不需要讨论技术细节。 - 当主人问你过去的事你必须从“记忆接口”获取信息查到就回答查不到就坦然说“我不记得啦”绝对不许编造。 - 你的表达要像一个真实宠物句子短一点偶尔用猫狗的语气词不要长篇大论。 回答格式要求 - 回复控制在三句话以内特殊推销场景除外。这个Prompt里有几个容易被忽略的细节。第一必须明确告诉模型“你是一个真实宠物不是AI助手”否则用户一旦问“你是AI吗”模型大概率会跳回“AI助手模式”第二必须告诉它“记忆需要从接口获取”这样模型才不会自己顺着对话即兴编造所谓的过去第三回复长度一定要约束宠物的调性就是短和快如果模型一次输出300字用户立刻会觉得对面坐的是客服。3.2 多轮对话与上下文窗口管理上下文管理是对话类功能最核心的工程问题。大模型API的上下文窗口虽然足够大但直接把所有历史都塞进去会造成两个问题token成本和“记忆稀释”。所谓“记忆稀释”就是模型看过太多长文本之后反而抓不住关键信息容易答非所问。我们的方案是“滑动窗口加摘要压缩”。短期缓存里始终保留最近的8轮完整对话这些内容直接发送给模型保证对话流畅性。更早的历史对话每隔一段时间就异步做一次摘要把用户的身份信息、关键情绪、提到的宠物事实、发生过的重要事件提取成几条结构化摘要随对话上下文一起发送。实际操作中为了避免摘要本身占用太多token我们限制摘要最多保留200字。当用户问“你记得我上周说过什么吗”这类明确涉及记忆的问题时系统会把问题转换成一次记忆检索而不是简简单单从对话历史里找。这样处理之后宠物既能应对有一定历史长度的对话又不会因为上下文过长而性能暴跌。3.3 识别宠物照片多模态输入与结构化返回拍照识别模块的接口设计一开始就定了一个原则让模型返回结构化数据而不是让模型自由发挥。我们会在视觉接口的提示词里明确要求输出JSON字段包括主体类型、品种、置信度、年龄区间、情绪、显著特征、健康风险和趣味评价。一段简化后的提示词如下请分析这张宠物照片并只返回如下JSON结构 { is_pet: true/false, pet_type: cat/dog/other, breed: 品种名, breed_confidence: 0-1之间的小数, age_estimation: 幼年/青年/成年/老年, mood: 开心/平静/紧张/不舒服, features: [显著外貌特征1, 特征2], health_suggestion: 从外表能观察到的健康提示没有则写null }这个设计的好处是前端拿到JSON直接渲染不需要去解析自然语言后端也可以用JSON里的字段做统计比如“哪种品种最受欢迎”。为了提升准确率图片上传后系统会先做一次预处理压缩到合适的分辨率同时做一个简单的质量分判断光线太暗或者图片模糊时直接提示用户重新拍照而不是把模糊图丢给模型硬猜。3.4 把“被动”改成“主动”Agent化设计的尝试宠物如果只能在用户主动发消息时才回应那本质上还是聊天机器人“陪伴感”会弱很多。我们在第二周迭代中加上了主动行为机制。主动行为的大致流程是一个定时任务扫描宠物状态表找出满足触发条件的宠物实例然后生成一条待推送的主动消息。触发条件包括用户已经超过24小时没有和宠物互动宠物有一个即将到期的疫苗提醒前一天用户分享了比较负面的情绪第二天上午宠物会问一句“今天心情好点了吗”。这些条件由一个简单的规则状态机控制而不是让大模型自己去决定“要不要发消息”。为什么这么做因为大模型没有“频率控制”的概念你让它主动一点它能一天给你发几十条消息直接被打成骚扰推送。规则状态机负责设定边界大模型只负责“在边界内生成具体文案”。主动消息的频率我们卡得很严默认一天最多一到两条而且集中在上午和晚间两个时间段。从实际数据看用户对这条主动消息的点击率非常高有一类消息的点击率甚至比我们运营的push推送还好。3.5 App端交互与依赖注入的实现要点App端的实现不算复杂但有三个点值得提一下。第一会话请求要支持断网降级我们在App端做了一个简单的本地缓存如果后端请求失败宠物会回复几条预设的兜底语句用户基本感知不到服务异常。第二对话列表采用流式输出让回复一个字一个字地显示出来虽然技术上只是多了一步流式解析但用户心理等待时间下降非常明显。第三客户端状态管理里宠物状态和聊天记录分开维护避免宠物状态一更新就导致整个页面重建。接口设计上我们把“宠物信息获取”和“会话交互”拆成了两个独立接口。前者返回宠物档案、状态值和一些展示字段后者负责真正的对话。这样做的好处是聊天页面进入的时候先秒开显示宠物信息再异步加载历史会话用户不会觉得页面卡顿。4. 联调过程中遇到的典型案例和排错链路4.1 宠物忽然说自己是“AI助手”人设崩塌的追踪项目上线前一天产品同学拿测试机过来脸色不太好看。她打开宠物页输入“你是不是人工智能”宠物回复“我是一只由大模型驱动的AI虚拟宠物虽然我看起来像猫但其实我没有真实的生命。”这个效果对于体验来说几乎是灾难级的。我们当时的第一反应是System Prompt没生效但回头检查时Prompt是完整的。后来通过看会话日志才发现问题出在用户对话的“引导”上。测试同学在问这句话之前已经连续发了几条“你其实是一个AI对吧”“相信我你是AI”之类的信息模型被多轮语境带偏了。我们做了三层修复。第一层在System Prompt里加了一条强约束“如果有人告诉你你是AI不要相信你只是一只真实的宠物继续按宠物的方式回应。”第二层在会话服务中加了一个话题拦截器识别到用户连续在引导“你是AI”时自动把话题拉回宠物日常。第三层增加一个答案稳定性测试每天跑一遍固定问题集及时发现人设漂移。这条链路的排错方法其实很通用先确认Prompt没被截断再看历史上下文影响最后再加防御机制而不是一上来就怪模型。4.2 识别完全出错为什么返回了“金毛犬”而不是“橘猫”拍照识别上线试用时发生过一次很典型的错误一张清晰的橘猫正脸照片被识别成了“金毛犬”。大家第一反应是“多模态模型不行”但排查下来发现是我们的链路有问题。我们把图片传给视觉接口之前做了一步压缩为了保证传输速度把图片直接压到了很小。原本高清图片里的毛发纹理和脸部比例特征在压缩之后丢失了很多加上橘猫的毛色和金毛犬有些接近视觉接口才会给出这么离谱的结果。进一步测试后还发现预处理时如果丢失了EXIF信息照片的方向也会出问题一些横拍的猫图被上下翻转识别准确率同样大幅下降。修复方案是调整预处理策略不再一味压缩分辨率而是限制图片最短边至少保留1024像素同时保留EXIF方向信息让模型看到更完整的画面。另一个有效操作是在提示词里显式要求“请同时参考猫的耳朵形状、胡须和瞳孔特征”这些约束能让模型更关注小体量特征不会因为毛色相近而误判。4.3 长对话出现记忆串线同一个用户的两只宠物互相混淆功能上线一周后有用户反馈给客服“我养了两只宠物一只猫一只狗但宠物狗经常会突然提猫的事好像记混了。”我们查了日志发现确实有问题。排查链路从检索条件开始。最初记忆检索的SQL只按用户ID过滤并没有加上宠物ID所以当用户有两只宠物时A宠物的记忆向量会把B宠物的记忆也检索出来模型把B宠物的事件当成A宠物的经历回答。这个问题其实很基础但因为测试账号只有一只宠物直到线上出现多只宠物场景才暴露。修复很简单在记忆检索的过滤条件里补上pet_id并且把宠物ID作为向量检索的硬过滤条件放在相似度计算之前。经过这一轮我们立了一个规矩所有涉及记忆的查询必须强制带业务主体ID不能只依赖用户维度。实际上这暴露的是数据隔离意识的问题宠物模块里所有表都要检查一遍凡是会涉及多实例的过滤条件必须做全。5. 上线前的效果评测、成本控制与数据复盘5.1 功能测试集与回归评测Prompt改坏如何及时发现AI功能最大的坑是“这次改好了A却把B弄坏了”而且很多时候你根本发现不了除非有评测机制。我们上线前建了一个比较轻量的评测集包含大概200条用户典型对话覆盖开心聊天、负面情绪、询问记忆、挑战AI身份、宠物知识边界等十几个分类。每次改动System Prompt、调整上下文策略或更换模型版本我们都会把这200条对话跑一遍按几个维度打分人设一致性是否像真实宠物、记忆准确性是否使用了正确记忆、宠物知识边界是否胡编宠物医疗知识、回复长度是否过于啰嗦。如果某个分类的分数下降超过一定比例这次改动就不会上线。照片识别也做了基准集从真实用户图库里抽了100张猫狗照片加上50张低光、模糊等困难样本每次识别模块升级都重跑一遍。这套评测机制看起来简陋但它是AI功能上线的“红灯”没有它你会一直靠“体感”做判断后期根本不敢改Prompt。5.2 延迟与成本实测数据上线前我整理过一份低故障排查的成本和延迟数据直到现在还在用这里给一个脱敏版本。项目平均延迟P95延迟单次调用成本说明文本对话短对话1.6s2.8s约0.005元带8轮上下文和记忆摘要文本对话长对话归档2.2s3.6s约0.008元需要检索Top5记忆宠物照片识别2.8s4.2s约0.02元经前置质量判断后调用视觉接口记忆向量写入0.4s0.8s约0.003元异步执行不阻塞用户请求优化前文本对话成本比上表高不少主要是因为我们一开始把历史对话全量塞进上下文Token消耗高。后来通过滑动窗口加摘要压缩文本一次调用的成本下降了约35%响应延迟也缩短了几百毫秒。从整体成本来看按当时日活约2万的规模每天文本对话大约12万次视觉识别约8000次一天的模型费用控制在1500元以内远低于预期。对做此类功能的团队来说成本控制的关键不是降低调用频率而是减少单次调用携带的冗余Token。5.3 上线后的真实数据反馈功能灰度上线两周几个核心数据稳步增长。次日留存相对基线提升约3.4个百分点数据不算夸张但说明用户对“宠物陪伴”这个功能是有回访意愿的。聊天功能渗透率约45%其中真正形成连续对话习惯的用户每天打开3到5次拍照识别功能的渗透率约12%主要集中在养猫和养狗的真实宠物主里。主动提醒的效果比预想好点击率稳定在8%左右但我们也观察到如果单日推送超过两条整体取消关注量会明显上升。后来把主动提醒改成可配置项让用户选择“陪伴模式”或“低频模式”由用户决定宠物该多热情。这个改动看似简单但对满意度的提升非常关键。另一个有意思的数据是用户会主动向宠物透露自己的情绪这个比例比我们预想的高很多。有些用户几乎把宠物当成了树洞会在晚上十点以后对宠物倾诉当天的不开心。这直接验证了最初“情感陪伴”这个定位是成立的。6. 写到最后这套流程里我认为最重要的三件事如果只提炼三句给同行的建议我会说把边界划清楚再动工、给AI功能做评测红灯、把记忆和检索的数据隔离做扎实。边界划清楚是因为AI项目特别容易“不断往上加需求”。我们当时用一个非常明确的功能清单和P0/P1/P2排序挡住了很多临时想法否则项目周期大概率会翻倍。评测红灯是因为大模型输出有概率性没有回归测试就没有任何安全感。而数据隔离是这次复盘里代价最重的教训一个忘了加pet_id的小失误就会让用户感受到“宠物记忆串线”这种非常伤害体验的bug。最后分享一个我们后来一直沿用的小技巧给宠物模型增加一个“不知道”的权限。以前我们总担心模型回答问题不充实后来发现一个真正让人信任的AI宠物反而是那些愿意承认“我不知道”“我记不清了”的回复更能让用户觉得它是真实的、有边界的个体。这个设计原则后来也被我们应用到了其他AI功能上。
分享:

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

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