医疗数据自动化系统
完整的端到端解决方案,用于抓取医疗保健数据并自动填写网页表单 基于大型语言模型(LLM)的智能现场绘图。
这是做什么用的
A部分: 从政府网站(CNES)抓取医疗机构数据 B部分: 利用基于智能大型语言模型(LLM)的字段映射功能,自动填充网页表单中的抓取数据
见 PROJECT_OVERVIEW.md 翻译为中文是:“项目概述.md” 用于完整的架构和需求文档。
特点/功能
- 由Playwright支持的MCP服务器 (HTTP/JSON) 带有三个端点:
- POST /navigate_and_snapshot - 提取具有角色+名称的表单控件 - POST /set_field_values - 填写字段并验证(不提交) - POST /probe_alternatives - 寻找用于自我修复的替代选择器
- 带有三个命令的CLI(命令行界面):
- normalize - 将原始的CNES行数据转换为规范形式的字段 - map - 使用启发式方法+可选的大语言模型(LLM)创建目标映射 - fill - 使用映射+规范化数据填写表单(不提交)
- 基于角色的定位/定向:
- 主要的,重要的 page.get_by_role(role, name="...") (Playwright Python) 翻译为中文是:(Python 的 Playwright 库) - 备用方案:使用CSS/XPath进行调试和替代方案
快速入门
1. 设置
just setup这将安装依赖项和Playwright Chromium。
2. 抓取数据(A部分)
python cnes_page_scraper.py \
--uf "RIO DE JANEIRO" \
--municipio "ARARUAMA" \
--all-pages \
-o araruama.json输出: 包含医疗设施数据的结构化JSON
3. 数据标准化(B部分)
just normalize araruama.json payloads.json输出: payloads.json 带有已准备好用于表单填写的标准字段
4. 启动MCP服务器
just serve服务器运行于 http://localhost:8765
5. 创建智能地图(基于大型语言模型)
just map "https://docs.google.com/forms/d/YOUR_FORM_ID/viewform" mapping.json对于LLM增强的映射(需要 OPENAI_API_KEY):
python -m app.cli.main map --form-url "YOUR_FORM_URL" --out mapping.json --use-llm6. 填写表格
just fill "https://docs.google.com/forms/d/YOUR_FORM_ID/viewform" mapping.json payloads.json 0检查 filled.png 用于截图。
规范场
CNES Code (text)
Entity type (radio: hospital | clinic | laboratory | UPA | secretariat | other)
Trade Name (text)
Legal Name (text)
Legal nature (group) (text)
Managing body (M/E/D) (text)
Serves SUS (radio: YES | NO)
City (text)
State (UF) (text, required)规范化规则
CNES Code←cnes(字符串)Trade Name←nome_fantasiaLegal Name←razao_social(或为空)Legal nature (group)←natureza_juridica_grupoManaging body (M/E/D)←gestao(M|E|D) 可以翻译为“(机械|电子|设计)”或者根据具体上下文可能翻译为“(医疗|教育|设计)”等,这里提供的是一个较为通用的翻译,具体含义需结合上下文确定Serves SUS←SIM→YES,NAO/NÃO→NO(不区分大小写/不区分重音符号)City标题大小写形式的municipioState (UF)← 大写ufEntity type← 源自nome_fantasia:
- 包含 UPA → UPA - 包含 HOSP → hospital - 包含 LAB 或者 DIAGNOST → laboratory - 包含 CLIN 或者 AMBULAT 或者 POLI → clinic - 包含 SECRET → secretariat - 否则 → other
测试
just test测试:
test_normalize.py- 验证规范化(SIM→是,实体类型推导等)test_snapshot_contract.py- 验证快照响应结构
API 端点
POST /导航并截屏
请求:
{
"url": "https://docs.google.com/forms/...",
"wait": "networkidle",
"max_ms": 8000
}回答:
{
"url": "...",
"title": "Unit Record (public data)",
"controls": [
{"role": "textbox", "name": "CNES Code", "required": false, "visible": true},
{"role": "radiogroup", "name": "Entity type", "options": ["hospital", "clinic", ...]}
]
}POST /设置字段值
请求:
{
"url": "https://docs.google.com/forms/...",
"targets": {
"CNES Code": {"role": "textbox", "name": "CNES Code"}
},
"values": {
"CNES Code": "5684633"
},
"no_submit": true
}回答:
{
"filled": {"CNES Code": true},
"verifications": {"CNES Code": "5684633"},
"screenshot": "data:image/png;base64,..."
}POST /探测备选方案
请求:
{
"url": "https://docs.google.com/forms/...",
"around": {"role": "textbox", "name": "State (UF)"},
"hint": "uf|state"
}回答:
{
"candidates": [
{"role": "textbox", "name": "State (UF)"},
{"css": "input[aria-label='State (UF)']"},
{"xpath": "//div[.//div[text()='State (UF)']]//input[not(@type='hidden')]"}
]
}项目结构
mcp_form_filler/
app/
__init__.py
schemas.py # Pydantic models
utils.py # Normalization logic
mapping/
heuristics.py # Heuristic field matcher
llm_mapper.py # Optional OpenAI mapper
server/
main.py # FastAPI endpoints
browser.py # Playwright helpers
cli/
main.py # Typer CLI commands
tests/
test_normalize.py
test_snapshot_contract.py
justfile
pyproject.toml
README.md环境变量
OPENAI_API_KEY- 可选,用于增强型LLM映射
笔记
- 总是与……一起运行
--no-submit标志(从不点击最终提交按钮) - 使用Playwright的无障碍API进行稳定定位
- 启发式方法首先匹配精确的角色+名称(不区分大小写)
- 当启发式方法失败时,可使用LLM回退(需要API密钥)
- 截图已保存为
filled.png每次填充操作后
依赖项
- playwright版本大于等于1.40.0
- fastapi版本大于等于0.104.0
- uvicorn\[standard\] 版本 >= 0.24.0
- pydantic>=2.5.0
- 类型(typer)版本 >= 0.9.0
- httpx>=0.25.0(注:这表示使用版本0.25.0或更高版本的httpx库)
- orjson>=3.9.0
- python-dotenv >= 1.0.0
- Pillow>=10.1.0(中文可译为:“Pillow 库版本需大于等于 10.1.0”)
- openai>=1.3.0(可选)
许可证
麻省理工学院(MIT)
