医疗 AI 实战:零成本“饮食安全计算器”

2025-12-02 17:56:05
文章摘要
本文针对慢病管理中饮食记录繁琐、 API 调用成本高的痛点,提出了一套基于本地大模型的零成”解决方案。无需联网、隐私安全且能输出结构化营养数据。

目录

前言

在慢病管理和康复医疗中,饮食记录是核心环节。但长久以来,让患者把每日菜谱发给医生,效率太差,也无法精准计算热量。

引入大模型可以很好地解决问题。但在医疗领域,直接调用云 API 面临数据隐私合规问题,同时还有额外的长期运营成本——随着用户量增加,API 调用费用是一笔不小的开支。

本文将介绍一套本地化的解决方案,利用 Ollama 本地部署阿里 Qwen2.5 模型,配合 LangChain 的格式控制功能,构建一个无需联网、隐私安全且零 API 调用费用的饮食分析工具。

图片描述

一、 技术选型

为了实现这一目标,我们需要三个核心组件配合:

1. 本地部署工具:Ollama

我们选择 Ollama 来在本地服务器运行模型。 图片描述

优势:部署极其简单,且完全在内网运行,物理隔绝了数据泄露风险。

2. 基础模型:Qwen2.5-7b

在信息提取任务上,70 亿参数(7b)的模型已经在速度和精度之间取得了很好的平衡。 图片描述

优势:阿里的 Qwen2.5 在理解中文指令和输出标准格式方面表现优秀,特别适合此类结构化提取任务。

3. 流程控制:LangChain v1

大模型有时候会废话连篇。LangChain v1 提供了一项关键功能——结构化输出(Structured Output)图片描述

优势:通过严格的格式检查,强制模型只输出我们需要的数据格式,避免系统解析报错。


二、 实操步骤

Step 1. 环境准备

首先,我们需要在本地服务器上把模型跑起来。Ollama 让这一步变得非常简单,只需几行命令即可完成服务启动。

# 1. 安装 Ollama (以 Linux 为例)
curl -fsSL https://ollama.com/install.sh | sh

2. 下载 Qwen2.5 7b 模型

ollama pull qwen2.5:7b

3. 启动后台服务

ollama serve

Step 2. 定义数据标准

为了让后续的程序能计算热量,我们必须规定好模型输出的数据格式。模型不能只回一句“好的”,而必须返回计算机能读取的结构化数据。

LangChain 允许我们利用 Pydantic 预先定义好这个**“数据模板”**:

from langchain_core.pydantic_v1 import BaseModel, Field
from typing import List

定义单个食物的数据格式

class FoodItem(BaseModel):
food_name: str = Field(description="食物的标准名称,例如’肉包’、‘豆浆’")
quantity: str = Field(description="食物的数量或预估重量,例如’2个’、‘300ml’")
estimated_calories: int = Field(description="基于常识预估的单项总热量(卡路里)")

定义整体输出格式(支持一餐包含多种食物)

class DietLog(BaseModel):
items: List[FoodItem] = Field(description="这一餐中包含的所有食物列表")

Step 3. 构建提取流程

接下来,我们将本地模型与刚才定义的数据标准结合起来。这一步的核心是告诉模型:“你是一个营养师助手,请严格按照我给定的 JSON 格式提取信息,不要说废话。”

from langchain_community.chat_models import ChatOllama
from langchain_core.prompts import ChatPromptTemplate

1. 连接本地运行的 Ollama 服务

llm = ChatOllama(model="qwen2.5:7b", temperature=0, format="json")

2. 启用格式控制功能

这一步确保模型输出的结果一定符合我们在第二步定义的 DietLog 格式

structured_llm = llm.with_structured_output(DietLog)

3. 设定指令

system_prompt = """你是一位专业的营养师助手。
你的任务是从用户的自然语言描述中,提取出食物信息。
请严格按照 JSON 格式输出,不要包含任何额外的解释性文字。
对于热量估算,请依据中国常见食物标准进行保守估计。"""

prompt = ChatPromptTemplate.from_messages([
("system", system_prompt),
("human", "{input}"),
])

4. 串联流程

chain = prompt | structured_llm

Step 4. 业务逻辑对接

模型提取出的数据只是第一步。在实际应用中,为了保证医学严谨性,我们不能完全依赖模型“乱猜”的热量,而是应该拿模型提取出的食物名去查询标准的营养数据库

以下代码展示了如何将 AI 提取的数据与标准数据库结合:

# 模拟一个本地的标准营养数据库
def query_nutrition_db(food_name: str):
    # 实际场景中,这里会连接 SQL 数据库
    db_mock = {
        "肉包": 250, # 单位热量
        "豆浆": 35   # 每100ml热量
    }
    # 简单的匹配逻辑
    for key, val in db_mock.items():
        if key in food_name:
            return val
    return None

主处理函数

def process_diet_input(user_input: str):
print(f"用户输入: {user_input}")

# 1. 使用模型将自然语言转化为结构化数据
try:
    result: DietLog = chain.invoke({"input": user_input})
except Exception as e:
    return f"解析失败: {e}"

# 2. 用标准数据库校准数据
final_report = []
for item in result.items:
    # 查询标准库
    db_cal = query_nutrition_db(item.food_name)
    
    source = "AI预估"
    if db_cal:
        source = "标准库修正"
        # 注:实际开发中需增加单位换算的逻辑
        
    final_report.append({
        "食物": item.food_name,
        "份量": item.quantity,
        "热量": item.estimated_calories,
        "数据来源": source
    })
    
return final_report

— 运行效果测试 —

if name == "main":
text = "早上吃了两个肉包子和一杯豆浆"
report = process_diet_input(text)
import json
print(json.dumps(report, indent=2, ensure_ascii=False))

Step 5. 实际运行效果

当用户输入:“早上吃了两个肉包子和一杯豆浆

系统后台会输出标准的 JSON 数据,可以直接存入患者的健康档案中:

[
  {
    "食物": "肉包子",
    "份量": "2个",
    "热量": 500,
    "数据来源": "标准库修正" 
  },
  {
    "食物": "豆浆",
    "份量": "1杯",
    "热量": 150,
    "数据来源": "标准库修正"
  }
]

总结与建议

相比于按次收费的云 API,本地部署属于一次性硬件投入,后续无论用户量怎么增长,都不会产生额外的 Token 费用。

而且患者不再需要复杂的录入操作,只需像聊天一样说话,系统即可自动完成记录。

利用这套方案,我们能以更低的门槛提升饮食管理的智能化水平,帮助慢性病患者实现长周期的精细化管理。

声明:该内容由作者自行发布,观点内容仅供参考,不代表平台立场;如有侵权,请联系平台删除。