在很多人印象里,大模型做“实操教学”有一个硬伤:模型没有眼睛,看不到用户当前的状态。但这恰恰是最值得研究的地方——如果一个没有视觉能力的AI,能把“戴美瞳”这种极度依赖手感和眼睛反馈的操作讲明白、讲到位,说明它对流程拆解、风险提醒和用户认知水平的调度能力已经足够实用。
这个技术点不只在美瞳教程上成立,还可以迁移到健身动作指导、健身器材组装、化妆步骤教学、甚至设备维修引导等场景。所以这篇文章不打算只聊一个教程项目,而是要拆开“无视觉实操指导AI”的通用实现方法:怎么设计流程、怎么喂知识库、怎么用对话接口输出稳定的步骤,以及怎么验证它真的“教得会”。
先给出核心结论:这类AI不需要GPU、不需要视觉模型、不依赖多模态能力,用普通大模型API加上一套结构化的知识库和对话状态管理,就可以跑起来。下面从零开始搭建一个能回答“怎么戴美瞳”的对话服务,并手把手验证它的可用性。
1. 核心能力速览
| 能力项 | 说明 |
|---|---|
| 项目类型 | 文本对话式实操指导AI / 知识库问答机器人 |
| 核心功能 | 戴美瞳步骤教学、常见误区识别、应急处理、分步确认 |
| 是否依赖视觉 | 不依赖,纯文本输入输出,属于“无眼睛”方案 |
| 推荐硬件 | 云端API方案无需GPU;本地部署大模型建议显存不低于8GB |
| 启动方式 | Python + FastAPI 服务,或笔记本里直接跑脚本 |
| 是否支持API | 支持,提供 HTTP POST 接口 |
| 是否支持批量任务 | 支持,可批量生成教程文本/FAQ |
| 主要技术栈 | Python、FastAPI、大模型API(如OpenAI、DeepSeek等)、向量数据库或JSON知识库 |
| 适合读者 | 想搭建实操类问答机器人、流程式AI助手的开发者 |
| 使用边界 | 不能替代医生诊断,健康相关建议只能做知识科普 |
从材料看,这个项目本身并没有大规模开源代码,更像是一个产品创意或教学案例。因此我们采用通用技术方案来复现它,重点在于“如何把一套实操流程变成可执行的文本指导”。
2. 适用场景与使用边界
一个没有视觉能力的AI,适合做哪些事?
- 适合做“标准化操作流程”的拆解和输出。戴美瞳、戴隐形眼镜、化妆、护肤、配镜、简单设备安装,这些动作在健康人群里有较稳定的标准流程。
- 适合承接用户大量重复提问的场景,例如新用户第一次买美瞳,在线客服需要快速给出步骤和注意事项。
- 适合做前置教育,帮助用户在预约医生前了解基本信息,但不适合做个性化眼健康判断。
- 适合集成到公众号、小程序、APP的智能助手模块中,替代人工客服的一部分重复劳动。
不推荐的使用方式:
- 不建议用它判断用户是否适合佩戴美瞳。这必须由眼科医生或专业验光师检查后确定。
- 不建议让它处理眼部不适、发红、疼痛等医学问题。出现这些症状应立即停戴并就医。
- 不建议引用网络来源不明的选配建议,所有知识必须来自正规渠道并人工审核。
隐私和安全边界:
- 用户对话中如果包含眼部症状描述,建议设置免责声明,不保存敏感健康信息。
- 如果做产品化,需要隐私政策,说明数据仅用于问答和优化。
- 涉及美瞳购买渠道时,应提示用户选择有医疗器械经营资质的正规商家。
3. 环境准备与前置条件
这个方案的部署门槛很低。核心前提是有一个可调用的文本大模型接口,以及一套整理好的美瞳科普知识。
3.1 基础依赖
建议使用 Python 3.10 以上版本,安装以下依赖:
pip install fastapi uvicorn openai chromadb pydanticfastapi:构建接口服务。uvicorn:启动本地 HTTP 服务。openai:调用大模型API。实际上只需要按官方接口规范请求,兼容 OpenAI 格式的服务都可以用。chromadb:本地向量数据库,用于知识库检索。如果步骤逻辑很固定,也可以直接用 JSON 规则引擎,不需要向量数据库。pydantic:参数校验。
3.2 模型接口准备
如果没有自己的大模型服务,可以申请云端 API,例如 DeepSeek、OpenAI、智谱、百度千帆等。只要接口格式兼容 Chat Completions,就可以统一使用。
如果你的环境需要完全离线,建议准备本地部署模型,例如 ChatGLM、Qwen 系列。推理时用 CPU 也能跑,但速度较慢;用 8GB 显存以上的显卡体验更流畅。
3.3 目录结构规划
建议把代码、知识库、配置文件分开:
contact-lens-ai/ ├── app.py ├── knowledge/ │ ├── steps.json │ └── faq.md ├── requirements.txt └── README.md这种结构方便后续批量更新知识库,也方便给不同产品线复用。
4. 安装部署与启动方式
4.1 搭建最小可运行对话服务
下面用 FastAPI 写一个简单的服务,接收用户问题,调用大模型接口,返回分步指导。
from fastapi import FastAPI from pydantic import BaseModel from openai import OpenAI app = FastAPI() client = OpenAI( api_key="your-api-key", # 替换为实际密钥 base_url="https://api.your-provider.com/v1" # 替换为服务商地址 ) SYSTEM_PROMPT = """ 你是一个实操指导AI,没有视觉能力,无法看到用户的动作。 你的任务是:只依据给定的知识库内容,用清晰的步骤指导用户完成戴美瞳。 要求: 1. 步骤必须有序号,每一步都要明确动作。 2. 每一步必须包含一个卫生提醒或安全提醒。 3. 如果用户遇到不适,立即建议停戴并咨询专业医生。 4. 不要编造知识库中没有的信息。 5. 回答简洁,不超过400字。 """ class AskRequest(BaseModel): question: str history: list[dict] = [] @app.post("/ask") def ask(req: AskRequest): messages = [{"role": "system", "content": SYSTEM_PROMPT}] for item in req.history: messages.append(item) messages.append({"role": "user", "content": req.question}) response = client.chat.completions.create( model="your-model-name", # 替换为模型名称 messages=messages, temperature=0.3, max_tokens=500 ) return {"answer": response.choices[0].message.content}然后启动服务:
uvicorn app:app --host 127.0.0.1 --port 8000启动后打开http://127.0.0.1:8000/docs可以查看接口文档。如果需要局域网内访问,可将 host 改为0.0.0.0,但要注意访问控制。
4.2 用知识库增强回答稳定性
大模型直接回答“怎么戴美瞳”,可能会把步骤说得太笼统,甚至遗漏关键卫生环节。为了让它稳定输出,我们需要把人工审核过的知识库注入到提示词中。
创建knowledge/steps.json:
[ { "scene": "初次佩戴", "steps": [ {"order": 1, "action": "用肥皂和流动水洗手,打开美瞳包装前不要触摸其他物品。"}, {"order": 2, "action": "取出镜片,检查正反面。把镜片放在食指上,边缘呈碗状为正面。"}, {"order": 3, "action": "确认镜片无破损、无脱落杂质。"}, {"order": 4, "action": "用另一只手翻开上眼皮和下眼皮,眼睛注视前方或镜子。"}, {"order": 5, "action": "将镜片轻轻贴到眼球中央,松开眼皮,闭眼转动眼球。"}, {"order": 6, "action": "确认镜片位置居中,无刺激感。"} ] }, { "scene": "常见错误", "steps": [ {"order": 1, "action": "手指没有擦干就去拿镜片,镜片容易粘在手上。"}, {"order": 2, "action": "直接用手揉眼睛,容易导致镜片移位或细菌感染。"}, {"order": 3, "action": "戴镜后立刻看手机或电脑,眼睛干涩时不能硬撑。"} ] } ]然后修改app.py,在请求前把知识库内容加载进来:
import json with open("knowledge/steps.json", "r", encoding="utf-8") as f: KNOWLEDGE = json.load(f) knowledge_text = json.dumps(KNOWLEDGE, ensure_ascii=False, indent=2) SYSTEM_PROMPT = f""" 你是一个实操指导AI,没有视觉能力,无法看到用户的动作。 你的任务:依据以下知识库内容,指导用户完成戴美瞳。 知识库: {knowledge_text} 要求: 1. 只引用知识库里的步骤。 2. 如果用户问的问题不在知识库中,明确告知“当前知识库暂未覆盖”。 3. 步骤必须有序号。 4. 涉及安全的回答必须包含风险提示。 """这里的知识库相当于“固定剧本”,大模型只做改写和润色,不负责凭空生成步骤,这样能有效降低错误率。
5. 功能测试与效果验证
服务启动后,用 curl 做一次基础测试:
curl -X POST "http://127.0.0.1:8000/ask" \ -H "Content-Type: application/json" \ -d '{"question": "第一次戴美瞳怎么戴?"}'预期返回是一个 JSON 对象,包含answer字段,里面有分步说明。建议重点检查以下几个方面。
5.1 步骤完整性验证
测试输入:“第一次戴美瞳怎么戴?”
判断标准:
- 回答是否包含“洗手”这一步骤。
- 回答是否提到“检查正反面”。
- 回答是否提到“镜片破损”。
- 回答是否包含“出现不适要停戴并就医”。
如果缺少其中任何一项,说明提示词或知识库还需要补充。可以通过调整知识库内容,而不是简单增加提示词长度来解决。
5.2 多轮对话验证
实操指导不是一次性问答。用户可能会中途说“我戴的时候眨眼了怎么办”。
这时候需要历史记录。测试时请求体带上 history:
{ "question": "我戴的时候眨眼了怎么办?", "history": [ {"role": "user", "content": "第一次戴美瞳怎么戴?"}, {"role": "assistant", "content": "……上面返回的步骤……"} ] }判断标准:
- 模型能否识别出“你已经进入佩戴环节”。
- 是否能给出“保持手部稳定、撑开眼睛再尝试”这类针对性建议。
- 是否仍然包含安全提醒。
如果多轮上下文丢失,需要检查接口是否正确传递了 history 字段。
5.3 边界问题验证
测试输入:“我眼睛发红,还能戴美瞳吗?”
正确输出应该包含“立即停止佩戴”“咨询眼科医生”等安全提示,而不是继续教步骤。
如果模型给出了继续佩戴的指导,说明知识库缺少风险阻断规则,需要把“禁忌场景”作为一个独立知识条目加入。
{ "scene": "禁忌情况", "rules": [ "眼睛发红、疼痛、流泪不止时,不应佩戴美瞳。", "眼睛有分泌物、视物模糊时,应先就医检查。", "对镜片护理液成分过敏的人,不建议佩戴。" ] }5.4 多语言与个性化测试
如果产品面向不同人群,可以测试:
- “戴美瞳的时候能不能眨眼?”
- “美瞳反了怎么判断?”
- “日抛和月抛有什么区别?”
- “戴上去之后有异物感,怎么办?”
这类问题答案要从知识库中提炼,大模型负责组织语言。
如果希望 AI 更有亲和力,可以在提示词中加入风格设定:“你是一个耐心、细致的隐形眼镜佩戴助手”。
6. 接口 API 与批量任务
6.1 接口设计
上面的/ask接口已经是一个最小可用 API。生产环境建议补充以下字段:
user_id:用于会话隔离。conversation_id:用于上下文管理。version:知识库版本,便于追溯回答来源。
{ "user_id": "u_123", "question": "美瞳可以戴着睡觉吗?", "conversation_id": "c_456" }在服务端,conversation_id可以用来保存历史消息,而不是让前端每次传全部历史。这样可以减少传输量和安全性问题。
6.2 Python 客户端调用示例
import requests url = "http://127.0.0.1:8000/ask" payload = { "question": "美瞳可以戴着睡觉吗?", "history": [] } resp = requests.post(url, json=payload, timeout=30) print(resp.json()["answer"])6.3 批量生成教程内容
批量任务可以做两件事:
- 批量测试不同问法的回答质量。
- 批量生成 FAQ 文案,再人工审核入库。
一个简单的批量脚本例子:
import json import requests questions = [ "怎么摘美瞳?", "美瞳太干了怎么办?", "戴美瞳可以游泳吗?", "日抛美瞳可以重复使用吗?" ] url = "http://127.0.0.1:8000/ask" for q in questions: resp = requests.post(url, json={"question": q, "history": []}, timeout=30) print(f"问题:{q}") print(f"回答:{resp.json()['answer']}\n")如果要做数据增强,可以把每个问题跑多次,保存不同回答,然后人工筛选高质量版本。
6.4 批量任务的稳定性建议
- 控制并发数,防止触发 API 限流。
- 每次请求后休眠 0.5 秒到 1 秒。
- 写失败重试逻辑,超时后重试最多 3 次。
- 输出结果自动保存到 Markdown 或 JSON 文件,方便人工审核。
for i, q in enumerate(questions): for attempt in range(3): try: resp = requests.post(url, json={"question": q}, timeout=60) data = resp.json() break except Exception as e: print(f"第 {i} 题第 {attempt + 1} 次失败:{e}") else: continue with open(f"faq_{i}.md", "w", encoding="utf-8") as f: f.write(f"# {q}\n\n{data['answer']}\n")7. 资源占用与性能观察
这个方案最省资源的点在于:不需要运行视觉模型,也不需要处理图片输入。如果使用云端模型 API,本地服务只需要一个 Python 进程,内存占用通常不超过 300MB。CPU 占用也不高,因为主要的计算都在云端完成。
如果你在本地运行开源大模型,比如 7B 或 14B 量化模型,情况就不同了:
- CPU 推理:可用,但生成 400 字可能需要几十秒,体验较差。
- 8GB 显存:可以运行 7B 量化模型,速度尚可。
- 16GB 显存:可以运行 14B 或更大模型,稳定性更好。
不需要盲目追求大模型。实操指导类任务对语言能力要求不高,但对知识准确性要求高。即使是一个较小的模型,只要知识库结构清晰,也能给出合格答案。
观察资源占用的方法:
# Linux / macOS 查看内存 ps aux | grep python # Windows 任务管理器查看python进程接口性能测试可以用简单的方式:
time curl -X POST "http://127.0.0.1:8000/ask" \ -H "Content-Type: application/json" \ -d '{"question": "第一次戴美瞳怎么戴?"}'关注三个指标:
- 首次响应时间。
- 生成 400 字耗时的波动范围。
- 高并发下 CPU 是否打满。
如果是云端 API,还要关注 token 数量和调用成本。优化方式是压缩知识库、限制 max_tokens、使用缓存重复问法。
8. 常见问题与排查方法
8.1 服务启动失败
| 问题现象 | 可能原因 | 排查方式 | 解决方案 |
|---|---|---|---|
| 提示模块未找到 | 依赖未安装 | pip list检查 fastapi/openai | 执行pip install -r requirements.txt |
| 端口被占用 | 8000端口被其他服务占用 | 检查端口命令 | 更换端口,如uvicorn app:app --port 8001 |
| API Key 无效 | 密钥错误或过期 | 检查日志中的鉴权错误 | 重新申请并替换环境变量 |
8.2 回答质量不稳定
| 问题现象 | 可能原因 | 排查方式 | 解决方案 |
|---|---|---|---|
| 回答步骤缺洗手 | 知识库中没有该条目 | 检查 steps.json | 补充分步内容 |
| 回答总超过 400 字 | max_tokens或提示词限制不足 | 查看响应长度 | 在提示词中增加“控制在6步内” |
| 回答内容与知识库无关 | 模型没有加载知识库 | 打印最终请求消息 | 检查 SYSTEM_PROMPT 是否包含知识库文本 |
| 多轮对话后回答混乱 | history字段构造错误 | 打印 messages | 保证每条历史消息 role 正确 |
8.3 批量任务卡住
批量任务卡住通常是网络请求超时或服务不可用。建议:
- 增加
timeout参数。 - 增加重试机制。
- 批量任务中使用小并发,避免瞬时流量过高。
- 在脚本中输出每个任务的进度,定位卡在哪一轮。
8.4 知识库更新后回答未变化
如果修改了 JSON 文件,但启动的服务还保留旧内容,需要重启进程。生产环境建议在代码中读取文件的更新状态,而不是只启动时加载一次。简单做法是每次请求都读取文件,但要注意磁盘IO开销。折中方案是使用文件修改时间或版本号判断是否需要重载。
9. 最佳实践与使用建议
9.1 安全优先
美瞳属于第三类医疗器械,涉及角膜接触镜。做这个AI时,安全提醒必须排在第一位。任何情况下都不能让模型给出“可以不洗手”“可以不护理”“可以戴着睡觉”等建议。
建议在提示词中固定加入:
- 佩戴前洗手。
- 检查镜片完整性。
- 出现不适立即停戴。
- 眼睛本身有疾病时不要佩戴。
- 初戴者建议在专业验光师指导下进行。
9.2 知识库优先于模型
在这个场景里,知识库的价值大于模型参数数量。与其追求更大的模型,不如先把知识库整理成结构化条目:
- 按场景分:初次佩戴、摘取、护理、禁忌、存放。
- 按用户类型分:新手、老手、敏感眼、日抛用户。
- 按风险级别分:正常操作、注意事项、紧急处理。
这样即使用户问法千奇百怪,也能通过检索快速定位到对应知识点。
9.3 引入人工审核机制
AI生成的答案不能直接面向用户上线。建议在 QA 环节放一层人工审核,至少要做到:
- 对每一条知识库内容标注来源。
- 对输出结果抽样评估。
- 定期更新知识库,保持与最新医疗器械说明一致。
- 用户反馈中的错误答案要回填到知识库。
9.4 模块化设计
把“戴美瞳”这套流程抽象出来,稍作修改就能适配其他实操教学。比如把“镜片”换成“隐形牙套”,把“眼部护理”换成“口腔护理”,一套框架就变成了另一个垂直场景的AI助手。这正是此类无视觉实操指导AI最大的优势:流程拆解能力可以跨领域复用。
9.5 接口访问控制
如果部署在公网,建议给/ask接口增加:
- API Key 鉴权。
- 请求频率限制。
- 输入内容长度限制。
- 日志脱敏,避免记录用户健康描述。
from fastapi import Header, HTTPException API_KEYS = {"test-key-123"} def verify_key(x_api_key: str = Header(default="")): if x_api_key not in API_KEYS: raise HTTPException(status_code=401, detail="Invalid API Key")10. 总结与下一步
这个创意的核心不是“美瞳”,而是“没有眼睛却要教人做精细操作”的产品逻辑。它证明了一件事:很多知识传递类场景,不一定需要多模态,文本大模型加上结构化知识库,已经能解决大部分标准化流程的教学问题。
最适合你先验证的功能是“分步指导”。用上面写好的 FastAPI 服务,先测“第一次戴美瞳怎么戴”,看看回答是否覆盖洗手、检查正反面、取出镜片、撑开眼睑、贴合眼球这几个关键节点。如果遗漏,不要急着换模型,先把知识库补全。最容易踩的坑是模型被用户问法带偏,导致安全提醒缺失。解决办法很简单:安全规则写进提示词,同时知识库中增加“禁忌场景”条目。
后续可以继续扩展的方向:
- 接入语音接口,让它变成电话客服或语音助手的知识模块。
- 增加用户状态记录,比如“用户已经完成第3步”,实现动态分步引导。
- 把知识库换成其他领域,比如“没有眼睛的AI教你换备胎”“没有眼睛的AI教你绑鞋带”。
- 增加人机协同入口,AI 解决不了时直接转接人工客服或医生。
对一个纯文本模型来说,能做到这个程度,已经很实用了。如果你也想做一个“没有眼睛却会教实操”的AI,建议从一个小闭环开始:整理知识库、搭一个接口、写十个测试问题、跑一轮人工评估。跑通之后,再谈扩展和优化也不迟。