用 Langflow + DeepSeek 搭建病历与药品提取接口
文章目录
认识 Langflow:核心概念一、环境与安装二、运行与日常管理三、绘制:搭建流程四、编排:连线与配置五、固定结果与使用技巧六、把流程部署成接口1. 生成 Langflow API Key2. 查看接口地址3. 三种语言的调用示例4. 识别图片的调用5. 部署到生产服务器6. 公网部署的安全配置7. 返回结果提取路径小结用 Langflow + DeepSeek 搭建病历与药品提取接口
医疗场景里,病历、处方、药品照片往往散落在不同格式的文字和图片里。手动整理既慢又容易出错。借助 Langflow 和 DeepSeek 多模态模型,我们可以搭一条自动化流水线:输入一句话或一张照片,模型就按固定格式吐出结构化的「病历信息 + 药品及用量」。
本文从零讲起,覆盖安装、运行、搭流程、连线配置、固定输出格式,一直到把流程发布成 HTTP 接口供小程序和网站调用。全程不使用密钥明文。
认识 Langflow:核心概念
在动手之前,先花一分钟搞懂 Langflow 是什么,后面每一步会清晰得多。
Langflow 是什么?
Langflow 是一个开源的、可视化的大模型工作流搭建平台。它把底层的大模型调用、提示词、工具、记忆等能力封装成一个个「节点」,你只要在画布上拖拽节点、连线,就能搭出一条 AI 流程,无需写代码。它底层基于 LangChain / LangGraph,但把它复杂的编排过程做成了图形化界面。
四个核心概念:
| 概念 | 说明 | 本文对应 |
|---|---|---|
| Flow(流程) | 一条完整的 AI 工作流,由多个节点连线组成 | 「病历与药品提取」流程 |
| Component / Node(组件 / 节点) | 一个独立的功能单元,比如「输入」「调用模型」「输出」 | Chat Input、Language Model、Chat Output |
| Connection / Edge(连线) | 节点之间传递数据的箭头,决定数据流向 | Chat Input ──> Language Model ──> Chat Output |
| Port(端口) | 节点上的输入 / 输出接口,连线必须接在端口上 | 文本、图片等 |
理解节点的一条简单规律: 每个节点都是「吃进数据 → 做一件事 → 吐出数据」。例如 Language Model 节点:吃进你的问题(输入端口),调用 DeepSeek 得到回答(处理),再把回答吐出来(输出端口)。连线就是把上游节点的「输出」接到下游节点的「输入」。
为什么用 Langflow 搭这个场景?
- 不用写代码:拖拽即完成,适合快速验证想法。
- 可视化调试:每个节点都能单独点开看输入输出,哪一步错了看得一清二楚。
- 可复用、可迁移:流程能导出成 JSON,换台机器一键导入。
- 一键发布接口:搭好的流程可以直接暴露成 HTTP API,供任何程序调用。
掌握了这些概念,下面开始实战。
一、环境与安装
先确认两件事:已安装 Docker Desktop(Windows / macOS)或 Docker 引擎(Linux),且能正常拉取 Docker Hub 镜像。
然后运行 Langflow 容器:
docker run -d \
--name LangFlowDemo \
-p 7860:7860 \
-e LANGFLOW_DATABASE_USER=langflow \
-e LANGFLOW_DATABASE_PASSWORD=<你的数据库密码> \
-e LANGFLOW_SUPERUSER_USERNAME=langflow \
-e LANGFLOW_SUPERUSER_PASSWORD=<你的管理员密码> \
langflowai/langflow:latest \
langflow run
| 参数 | 作用 |
|---|---|
--name LangFlowDemo |
容器名称,后续管理都用它 |
-p 7860:7860 |
把容器内 7860 端口映射到本机,浏览器访问 localhost:7860 |
LANGFLOW_DATABASE_USER / PASSWORD |
外部数据库凭据(见下方说明) |
LANGFLOW_SUPERUSER_USERNAME / PASSWORD |
首次登录的管理员账号,必须设置,否则容器启动会报错 |
关于数据库的两个坑
LANGFLOW_DATABASE_USER/PASSWORD是给外部数据库(如 PostgreSQL)用的。Langflow 默认实际使用的是内置 SQLite,所以不搭外部数据库也能正常启动,这两个变量不填也无副作用;只有接入自己的 PostgreSQL 时才真正需要。LANGFLOW_SUPERUSER_*才是必填项:缺少它容器会报ValueError: Username and password must be set并退出。
启动后浏览器打开 http://localhost:7860,用刚才设置的管理员账号登录即可。
二、运行与日常管理
常用命令(LangFlowDemo 为容器名):
# 启动容器
docker start LangFlowDemo
# 重启容器
docker restart LangFlowDemo
# 停止容器
docker stop LangFlowDemo
# 查看实时日志
docker logs -f LangFlowDemo
访问地址始终是 http://localhost:7860。注意接口默认只在本机可访问,若要被小程序或网站调用,需要把 Langflow 部署到有公网地址的服务器(后文会讲)。
三、绘制:搭建流程
登录后新建一个流程,命名为「病历与药品提取」。本流程只用到 3 个节点,从左侧组件面板拖入画布即可:
- Chat Input:输入入口
- Language Model:调用 DeepSeek 多模态模型
- Chat Output:输出结果
配置模型节点(Language Model):
- Provider:
OpenAI Compatible - Base URL:
https://api.deepseek.com - Model:
deepseek-flash(多模态,支持图片,128k 上下文) - API Key:填自己的 DeepSeek 密钥,建议存入 Langflow 平台级的「Global Variables / Model Providers」凭证,不要把密钥写进流程本身
Chat Input 节点: 勾选 Text + Image 两种类型,既能输入文字,也能上传病历、处方或药品照片。
四、编排:连线与配置
三个节点的连线顺序很简单:
Chat Input ──> Language Model ──> Chat Output
| 节点 | 关键配置 |
|---|---|
| Chat Input | 打开 files,允许文字 + 图片输入 |
| Language Model | 选择已配置的 DeepSeek 凭证;System Message 填入固定格式模板 |
| Chat Output | 接收模型返回,用于界面展示与接口返回 |
固定输出模板(System Message):为了让输出永远对齐,在 Language Model 节点的 System Message 里写入:
你是病历与用药信息提取助手。请从用户的输入(文字或图片)中提取以下信息,严格按照下面的格式输出。识别不到的字段填写“未提供”,禁止编造任何内容。
【病历信息】
患者姓名:
性别年龄:
就诊日期:
就诊科室:
主治医生:
诊断结果:
【药品及用量】
1. 药品名称:
剂型:
每次用量:
用法频次:
2. ...
【其他医嘱】
五、固定结果与使用技巧
模型会始终按模板返回。例如输入:
患者张三,诊断:上呼吸道感染。用药:阿莫西林胶囊 每次0.5g 每日三次。
输出为:
【病历信息】
患者姓名:张三
性别年龄:未提供
就诊日期:未提供
就诊科室:未提供
主治医生:未提供
诊断结果:上呼吸道感染
【药品及用量】
1. 药品名称:阿莫西林胶囊
剂型:胶囊
每次用量:0.5g
用法频次:每日三次
【其他医嘱】
未提供
使用提示:实测发现,对短而清晰的输入,DeepSeek-flash 提取很准;但对信息堆在一起的长句、多药品混排,部分字段可能被识别成「未提供」。想稳定准确,建议让输入按固定句式书写,例如:
姓名:XX,性别年龄:XX,就诊科室:XX,诊断:XX。药品1:药品名 每次XX 用法XX;药品2:……
六、把流程部署成接口
流程只需搭建一次,之后所有程序(脚本 / 小程序 / 网站)都通过同一个接口调用。
1. 生成 Langflow API Key
登录后点击右上角头像 → Settings → Langflow API Keys → Add New,生成 Key。该 Key 只显示一次,请立即复制保存。之后所有接口调用都把这个 Key 放在请求头 x-api-key 中。
该 Key 属于敏感凭证,请勿写进文档、代码仓库或共享文件,丢失后需重新生成。
2. 查看接口地址
打开流程右上角 ⌘ 图标 → API access,即可看到:
POST http://<服务器地址>:7860/api/v1/run/<flow_id>?stream=false
本机测试时 <服务器地址> 填 localhost,供外部调用时换成公网地址。
3. 三种语言的调用示例
cURL:
curl -X POST "http://localhost:7860/api/v1/run/<flow_id>?stream=false" \
-H "Content-Type: application/json" \
-H "x-api-key: <你的APIKey>" \
-d '{"input_value":"患者张三,诊断:上呼吸道感染。用药:阿莫西林胶囊 每次0.5g 每日三次。","output_type":"chat","input_type":"chat"}'
Python:
import requests
url = "http://localhost:7860/api/v1/run/<flow_id>?stream=false"
r = requests.post(
url,
json={
"input_value": "患者张三,诊断:上呼吸道感染。用药:阿莫西林胶囊 每次0.5g 每日三次。",
"output_type": "chat",
"input_type": "chat",
},
headers={"x-api-key": "<你的APIKey>"},
timeout=120,
)
text = r.json()["outputs"][0]["outputs"][0]["results"]["message"]["text"]
print(text)
小程序 / 网页(JavaScript fetch):
const res = await fetch("http://localhost:7860/api/v1/run/<flow_id>?stream=false", {
method: "POST",
headers: {
"Content-Type": "application/json",
"x-api-key": "<你的APIKey>",
},
body: JSON.stringify({
input_value: "患者张三,诊断:上呼吸道感染。用药:阿莫西林胶囊 每次0.5g 每日三次。",
output_type: "chat",
input_type: "chat",
}),
});
const data = await res.json();
const text = data.outputs[0].outputs[0].results.message.text;
4. 识别图片的调用
图片通过请求体里的 files 字段传入(数组,填图片在服务器上的路径):
{
"input_value": "请识别这张图片中的病历和药品信息",
"output_type": "chat",
"input_type": "chat",
"files": ["/app/data/2026-10-14_07-00-25_中药处方.png"]
}
图片不在服务器上时,先上传再填路径,或用 base64 方式传入。
5. 部署到生产服务器
默认 localhost:7860 只有本机能访问。要让小程序、网站稳定调用,需把 Langflow 部署到有公网地址的云服务器。
第 1 步:准备服务器。 推荐 2 核 4G 起(DeepSeek 在云端推理,Langflow 本身占用不高),系统用 Linux(Ubuntu 22.04 / CentOS 等),安装 Docker:
curl -fsSL https://get.docker.com | sh
sudo systemctl enable docker && sudo systemctl start docker
同时准备一个域名,做 DNS 解析到服务器公网 IP。
第 2 步:迁移流程。 推荐方式:本机流程 → 右上角 ⌘ → Export 导出 JSON → 上传服务器 → 登录生产 Langflow 后 Import 导入,节点与固定模板会完整带过去。
第 3 步:运行生产容器。 关键差异在于端口只绑定在 127.0.0.1,并加上安全配置:
docker run -d \
--name langflow-prod \
-p 127.0.0.1:7860:7860 \
-e LANGFLOW_DATABASE_USER=langflow \
-e LANGFLOW_DATABASE_PASSWORD=<生产数据库密码> \
-e LANGFLOW_SUPERUSER_USERNAME=langflow \
-e LANGFLOW_SUPERUSER_PASSWORD=<生产管理员密码> \
-e LANGFLOW_AUTO_LOGIN=False \
-e LANGFLOW_SECRET_KEY=<一长串随机密钥> \
-e LANGFLOW_CORS_ORIGINS=<你的小程序/网站域名> \
langflowai/langflow:latest \
langflow run
- 端口只绑定
127.0.0.1:7860 仅允许服务器本机访问,由 Nginx 统一对外。 LANGFLOW_AUTO_LOGIN=False:关闭自动登录,强制鉴权。LANGFLOW_SECRET_KEY:设为足够长的随机字符串(如openssl rand -hex 32生成),别用默认值。LANGFLOW_CORS_ORIGINS:设为真实域名,不要用*,避免跨域 CSRF 与 token 盗用。
第 4 步:Nginx 反向代理 + HTTPS。 对外只开放 443。安装 Nginx 后写配置:
server {
listen 80;
server_name ai.你的域名.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name ai.你的域名.com;
ssl_certificate /etc/letsencrypt/live/ai.你的域名.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/ai.你的域名.com/privkey.pem;
client_max_body_size 50m;
location / {
proxy_pass http://127.0.0.1:7860;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
再用 Let's Encrypt 申请免费证书:
sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d ai.你的域名.com
启用并重载:
sudo ln -s /etc/nginx/sites-available/langflow /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
第 5 步:安全组 / 防火墙放行。 云厂商安全组里只放行 443(HTTPS)和 22(SSH),不要把 7860 开放到公网。本地防火墙同理:sudo ufw allow 443/tcp、sudo ufw allow OpenSSH、sudo ufw enable。
第 6 步:验证生产接口。 把请求地址换成域名后测试,返回正常即可:
curl -X POST "https://ai.你的域名.com/api/v1/run/<flow_id>?stream=false" \
-H "Content-Type: application/json" \
-H "x-api-key: <你的APIKey>" \
-d '{"input_value":"患者张三,诊断:上呼吸道感染。用药:阿莫西林 每次0.5g 每日三次。","output_type":"chat","input_type":"chat"}'
如果只想快速试用、不想买服务器,也可以用 frp / ngrok 做内网穿透,把本机 7860 映射成临时公网地址,但仅适合测试,不建议长期生产使用。
6. 公网部署的安全配置
| 配置项 | 说明 |
|---|---|
LANGFLOW_AUTO_LOGIN=False |
禁止自动登录,要求每次验证 |
更换 LANGFLOW_SECRET_KEY |
不要使用默认密钥 |
LANGFLOW_CORS_ORIGINS |
设为实际域名(不用 *),避免跨域 CSRF / token 盗用 |
| 反向代理 + HTTPS | 不要把 7860 端口直接暴露到公网 |
7. 返回结果提取路径
接口返回 JSON,提取文本的固定路径为:
data["outputs"][0]["outputs"][0]["results"]["message"]["text"]
返回内容即第五章的固定格式,每次调用会消耗 DeepSeek 额度(返回里有 token 用量统计)。
小结
用 Langflow 搭病历与药品提取,核心就三件事:三个节点、一段固定格式的 System Message、一个对外 HTTP 接口。流程搭好后,所有程序共用同一个接口,输入文字或图片,输出结构化结果。
生产上线时,重点放在安全加固上:关闭自动登录、更换密钥、限制 CORS、用 Nginx 反代 + HTTPS,并且绝不把 7860 端口直接暴露到公网。这样一条稳定的提取流水线就能正式投入使用了。