kv-extractor-mcp服务器
从任意、嘈杂或非结构化文本中使用大型语言模型(LLMs)提取结构化的键值对,并以多种格式(JSON、YAML、TOML)输出,同时保证类型安全。
服务介绍
灵活的键值提取 MCP 服务器
版本: 0.3.1
此 MCP 服务器使用 LLMs(GPT-4.1-mini)和 pydantic-ai 从任意的、嘈杂的或非结构化的文本中提取键值对。它确保类型安全并支持多种输出格式(JSON、YAML、TOML)。该服务器对任何输入都具有鲁棒性,并且总是尽可能地尝试结构化数据,但不保证完美提取。
🤔💡 为什么使用这个 MCP 服务器?
虽然许多大型语言模型 (LLMs) 服务提供了结构化输出功能,但此 MCP 服务器在键值提取方面具有独特的优势,尤其是在处理具有挑战性的现实世界文本时:
- 🔑🔍 自动键发现: 其核心优势在于能够自主识别并从未结构化的文本中提取相关的键值对,而无需预定义键。虽然典型的 LLM 结构化输出需要你指定要查找的键,但此服务器可以自行发现这些键,使其在多样且不可预测的数据中非常有效。
- 💪🧱 对复杂输入的强大鲁棒性: 它擅长处理任意的、嘈杂的或非结构化的文本,在这些情况下标准 LLM 结构化输出可能会失败。多步骤管道专门设计用于筛选和理解不完美的数据。
- 🌐🗣️ 高级多语言预处理: 在 LLM 处理之前,它利用 spaCy 进行日语、英语和中文(简体/繁体)的命名实体识别 (NER),通过提供丰富的上下文候选短语显著提高了这些语言的提取准确性。
- 🔄✍️ 迭代细化和类型标注: 与单次提取不同,此服务器采用复杂的管道,包括基于 LLM 的类型注释、基于 LLM 的类型评估以及基于规则/LLM 回退的规范化。这确保了更准确且上下文适当的类型。
- ✅🛡️ 保证类型安全和模式遵守: 最终使用 Pydantic 进行结构化,确保输出不仅结构化而且类型安全,并且针对定义的模式进行了验证,为下游应用提供了可靠的数据。
- 📊⚙️ 一致且可预测的输出: 即使提取是部分的或遇到问题,服务器也设计为始终返回格式良好的响应,这对于构建健壮的自动化系统至关重要。
发布说明
v0.3.1
- 更新:改进类型评估提示以进行稳健修正。
- 更新:在 README.md 中添加了此 MCP 服务器的优点。
v0.2.0
- 修复:zh-cn / zh-tw 的语言代码。
v0.1.0
- 初始发布
工具
/extract_json: 从输入文本中提取类型安全的键值对,并以 JSON 格式输出。/extract_yaml: 从输入文本中提取类型安全的键值对,并以 YAML 格式输出。/extract_toml: 从输入文本中提取类型安全的键值对,并以 TOML 格式输出。- 注意:由于 TOML 规范的限制,对象数组(字典)或深度嵌套结构无法直接表示。有关详细信息,请参阅下面的“关于 TOML 输出限制的注意事项”。
注意:
- 支持的语言:日语、英语和中文(简体:zh-cn / 繁体:zh-tw)。
- 提取依赖于 pydantic-ai 和 LLMs。不保证完美提取。
- 较长的输入句子将需要更多时间来处理。请耐心等待。
- 首次启动时,服务器将下载 spaCy 模型,因此初始过程会花费更长时间。
估计处理时间示例
| 输入标记 | 输入字符数(约) | 测量处理时间(秒) | 模型配置 |
|---|---|---|---|
| 200 | ~400 | ~15 | gpt-4.1-mini |
功能
- 灵活提取:能够处理任何输入,包括有噪声或损坏的数据。
- JP / EN / ZH-CN / ZH-TW 全面支持:通过自动语言检测(支持日语、英语、中文[简体: zh-cn / 繁体: zh-tw];其他语言将返回错误)使用spaCy NER进行预处理。
- 类型安全输出:使用Pydantic进行输出验证。
- 多种格式:以JSON、YAML或TOML格式返回结果。
- 强大的错误处理:即使在失败时也总是返回格式良好的响应。
- 高准确性:使用GPT-4.1-mini进行提取/注释和类型评估,并用Pydantic进行最终结构化。
测试场景
服务器已经使用各种输入进行了测试,包括:
- 简单的键值对
- 埋藏在噪音或非结构化文本中的重要信息
- 不同的数据格式(JSON、YAML、TOML)用于输出
处理流程
下面是server.py中实现的键值提取管道的处理流程图:
mermaid
flowchart TD
A[输入文本] --> B[步骤0: 使用spaCy语言检测然后NER预处理]
B --> C[步骤1: 键值提取 - LLM]
C --> D[步骤2: 类型注释 - LLM]
D --> E[步骤3: 类型评估 - LMM]
E --> F[步骤4: 类型规范化 - 静态规则 + LLM]
F --> G[步骤5: 使用Pydantic进行最终结构化]
G --> H[以JSON/YAML/TOML格式输出]
使用spaCy进行预处理(多语言NER)
此服务器使用spaCy结合自动语言检测从输入文本中提取命名实体之后再传递给LLM。支持的语言为日语 (ja_core_news_md)、英语 (en_core_web_sm) 和中文(简体/繁体, zh_core_web_sm)。
-
输入文本的语言是使用
langdetect自动检测的。 -
如果检测到的语言不是日语、英语或中文,服务器将返回错误:
Unsupported lang detected。 -
会根据需要自动下载并加载适当的spaCy模型。无需手动安装。
-
提取的短语列表如下所示包含在LLM提示中:
[预处理候选短语 (spaCy NER)]
以下是从输入文本中使用spaCy检测到的语言模型自动提取的短语列表。
这些短语代表了如姓名、日期、组织、地点、数字等被检测到的实体。
此列表仅供参考,可能包含无关或不正确的项目。LLM将自行判断并考虑整个输入文本来灵活推断最合适的键值对。
步骤详情
该项目的键值提取管道由多个步骤组成。每个步骤的详细信息如下:
步骤0: 使用spaCy预处理(语言检测 → 命名实体识别)
- 目的:自动检测输入文本的语言,并使用适当的spaCy模型(例如,
ja_core_news_md、en_core_web_sm、zh_core_web_sm)来提取命名实体。 - 输出:提取的短语列表,作为提示的一部分提供给LLM,以提高键值对提取的准确性。
步骤1: 键值提取 (LLM)
- 目的:使用GPT-4.1-mini从输入文本及提取的短语列表中提取键值对。
- 细节:
- 提示中包含了当同一键出现多次时返回列表格式值的指令。
- 少样本示例设计为包含列表格式的输出。
- 输出:例如
key: person, value: ["Tanaka", "Sato"]
步骤2: 类型注释 (LLM)
- 目的:使用GPT-4.1-mini推断步骤1中提取出的每个键值对的数据类型(int, str, bool, list等)。
- 细节:- 类型注解提示包括对列表和多值支持的说明。
- 输出: 示例:
key: person, value: ["Tanaka", "Sato"] -> list[str]
第3步:类型评估(LLM)
- 目的:使用GPT-4.1-mini来评估并修正第2步中的类型注解。
- 详情:
- 对于每个键值对,GPT-4.1-mini重新评估类型注解的有效性和上下文。
- 如果检测到类型错误或歧义,GPT-4.1-mini会自动更正或补充类型。
- 示例:将被提取为数字但实际上应为字符串的值进行更正,或者确定一个值是列表还是单个值。
- 输出:经过类型评估后的键值对列表。
第4步:类型规范化(静态规则 + LLM回退)
- 目的:将类型评估的数据转换成Python的标准类型(int, float, bool, str, list, None等)。
- 详情:
- 应用静态规范化规则(正则表达式或类型转换函数)将值转换为Python的标准类型。
- 示例:将逗号分隔的值转换为列表,"true"/"false"转换为布尔值,或将日期表达式转换为标准格式。
- 如果静态规则无法转换某个值,则使用基于LLM的类型转换回退机制。
- 无法转换的值安全地处理为None或str。
- 输出:Python类型规范化的键值对列表。
第5步:使用Pydantic进行最终结构化
- 目的:使用Pydantic模型(KVOut/KVPayload)验证并结构化类型规范化的数据。
- 详情:
- 将每个键值对映射到Pydantic模型,确保类型安全和数据完整性。
- 根据模式验证单个值、列表、空值以及复合类型。
- 如果验证失败,在保留尽可能多数据的同时附加错误信息。
- 最终输出以指定格式(JSON, YAML, 或 TOML)返回。
- 输出:类型安全且已验证的字典或指定格式(JSON/YAML/TOML)输出。
此流水线设计旨在支持未来的列表格式支持和Pydantic模式扩展。
关于TOML输出限制的说明
- 在TOML中,简单数组(例如
items = ["A", "B"])可以原生表示,但是
对象数组(字典)或深度嵌套结构由于TOML规范的原因不能直接表示。 - 因此,复杂列表或嵌套结构(例如
[{"name": "A"}, {"name": "B"}])将
作为“JSON字符串”存储在TOML值中。 - 这是一个设计选择,以防止因TOML规范限制而导致的信息丢失。
- YAML和JSON格式可以直接表示嵌套结构。
输入/输出示例
输入:
Thank you for your order (Order Number: ORD-98765). Product: High-Performance Laptop, Price: 89,800 JPY (tax excluded), Delivery: May 15-17. Shipping address: 1-2-3 Shinjuku, Shinjuku-ku, Tokyo, Apartment 101. Phone: 090-1234-5678. Payment: Credit Card (VISA, last 4 digits: 1234). For changes, contact support@example.com.
输出(JSON):
json
{
"order_number": "ORD-98765",
"product_name": "High-Performance Laptop",
"price": 89800,
"price_currency": "JPY",
"tax_excluded": true,
"delivery_start_date": "20240515",
"delivery_end_date": "20240517",
"shipping_address": "1-2-3 Shinjuku, Shinjuku-ku, Tokyo, Apartment 101",
"phone_number": "090-1234-5678",
"payment_method": "Credit Card",
"card_type": "VISA",
"card_last4": "1234",
"customer_support_email": "support@example.com"
}
输出(YAML):
yaml
order_number: ORD-98765
product_name: High-Performance Laptop
price: 89800
price_currency: JPY
tax_excluded: true
delivery_start_date: 20240515
delivery_end_date: 20240517
shipping_address: 1-2-3 Shinjuku, Shinjuku-ku, Tokyo, Apartment 101
phone_number: 090-1234-5678
payment_method: Credit Card
card_type: VISA
card_last4: 1234
customer_support_email: support@example.com
输出(TOML,简单情况):
toml
order_number = "ORD-98765"
product_name = "High-Performance Laptop"
price = 89800
price_currency = "JPY"
tax_excluded = true
delivery_start_date = "20240515"
delivery_end_date = "20240517"
shipping_address = "1-2-3 Shinjuku, Shinjuku-ku, Tokyo, Apartment 101"
phone_number = "090-1234-5678"
payment_method = "Credit Card"
card_type = "VISA"
card_last4 = "1234"输出(TOML,复杂情况):
toml
items = [{"name": "A", "qty": 2}, {"name": "B", "qty": 5}]
addresses = [{"city": "Tokyo", "zip": "160-0022"}, {"city": "Osaka", "zip": "530-0001"}]
注:对象数组或嵌套结构在TOML中以JSON字符串形式存储。
工具
1. extract_json
- 描述:从任意嘈杂文本中提取键值对,并将其作为类型安全的JSON(Python字典)返回。
- 参数:
input_text(字符串):包含嘈杂或非结构化数据的输入字符串。
- 返回:
{ "success": True, "result": ... }或{ "success": False, "error": ... } - 示例:
json
{
"success": true,
"result": { "foo": 1, "bar": "baz" }
}
2. extract_yaml
- 描述:从任意嘈杂文本中提取键值对,并将其作为类型安全的YAML(字符串)返回。
- 参数:
input_text(字符串):包含嘈杂或非结构化数据的输入字符串。
- 返回:
{ "success": True, "result": ... }或{ "success": False, "error": ... } - 示例:
json
{
"success": true,
"result": "foo: 1
bar: baz"
}
3. extract_toml
- 描述:从任意嘈杂文本中提取键值对,并将其作为类型安全的TOML(字符串)返回。
- 参数:
input_text(字符串):包含嘈杂或非结构化数据的输入字符串。
- 返回:
{ "success": True, "result": ... }或{ "success": False, "error": ... } - 示例:
json
{
"success": true,
"result": "foo = 1
bar = "baz""
}
使用方法
通过Smithery安装
要通过Smithery自动为Claude Desktop安装kv-extractor-mcp-server:
bash
npx -y @smithery/cli install @KunihiroS/kv-extractor-mcp-server --client claude
要求
- Python 3.9+
- OpenAI模型的API密钥(在
settings.json中的env下设置)
运行服务器
bash
python server.py
如果您想手动运行服务器。
MCP主机配置
当运行此MCP服务器时,必须通过命令行参数明确指定日志输出模式以及(如果启用)绝对日志文件路径。
--log=off: 禁用所有日志记录(不写入任何日志)--log=on --logfile=/absolute/path/to/logfile.log: 启用日志记录并将日志写入指定的绝对文件路径- 当启用日志记录时,这两个参数都是必需的。如果缺少任何一个参数、路径不是绝对路径或给定值无效,服务器将退出并显示错误。
示例:禁用日志记录
json
"kv-extractor-mcp-server": {
"command": "pipx",
"args": ["run", "kv-extractor-mcp-server", "--log=off"],
"env": {
"OPENAI_API_KEY": "{apikey}"
}
}
示例:启用日志记录(需要绝对日志文件路径)
json
"kv-extractor-mcp-server": {
"command": "pipx",
"args": ["run", "kv-extractor-mcp-server", "--log=on", "--logfile=/workspace/logs/kv-extractor-mcp-server.log"],
"env": {
"OPENAI_API_KEY": "{apikey}"
}
}
注意:
- 当启用日志记录时,日志仅写入到指定的绝对文件路径。相对路径或省略
--logfile会导致错误。- 当禁用日志记录时,不会输出任何日志。
- 如果缺少必需的参数或参数无效,服务器将无法启动并会打印错误消息。
- 日志文件必须可被MCP服务器进程访问和写入。
- 如果您遇到运行此服务器的问题,可能是由于缓存了旧版本的kv-extractor-mcp-server。请尝试使用最新版本(将
x.y.z设置为最新版本)的kv-extractor-mcp-server运行,如下所示。
json
"kv-extractor-mcp-server": {
"command": "pipx",
"args": ["run", "kv-extractor-mcp-server==x.y.z", "--log=off"],
"env": {
"OPENAI_API_KEY": "{apikey}"
}
}
许可证
GPL-3.0-or-later
作者
KunihiroS(及贡献者)