Update app.py
Browse files
app.py
CHANGED
|
@@ -20,10 +20,10 @@ class KnowledgeGraph:
|
|
| 20 |
relations: List[Relation] = field(default_factory=list)
|
| 21 |
|
| 22 |
class KnowledgeGraphManager:
|
|
|
|
| 23 |
def __init__(self):
|
| 24 |
self.graph = KnowledgeGraph()
|
| 25 |
print("Initialized a new, empty in-memory knowledge graph.")
|
| 26 |
-
# ... Manager 的所有内部方法保持不变 ...
|
| 27 |
def create_entities(self, entities_data: List[Dict]) -> List[Entity]:
|
| 28 |
new_entities = []
|
| 29 |
for e_data in entities_data:
|
|
@@ -75,146 +75,132 @@ class KnowledgeGraphManager:
|
|
| 75 |
|
| 76 |
kg_manager = KnowledgeGraphManager()
|
| 77 |
|
| 78 |
-
# --- 2. API 工具函数定义 (
|
| 79 |
-
|
| 80 |
-
# 它们的输入和输出类型都是 Gradio 原生支持的,因此不需要 lambda。
|
| 81 |
-
def create_entities(entities: List[Dict]) -> str:
|
| 82 |
-
# ... (函数实现和文档字符串保持不变) ...
|
| 83 |
"""在知识图谱中创建多个新实体。
|
| 84 |
|
| 85 |
Args:
|
| 86 |
-
|
| 87 |
|
| 88 |
Returns:
|
| 89 |
str: 表示成功创建的新实体的JSON字符串。
|
| 90 |
"""
|
| 91 |
-
new_entities = kg_manager.create_entities(entities)
|
| 92 |
return json.dumps([asdict(e) for e in new_entities], indent=2)
|
| 93 |
|
| 94 |
-
def create_relations(
|
| 95 |
-
"""在知识图谱中的实体之间创建多个新关系。
|
| 96 |
|
| 97 |
Args:
|
| 98 |
-
|
| 99 |
|
| 100 |
Returns:
|
| 101 |
str: 表示成功创建的新关系的JSON字符串。
|
| 102 |
"""
|
| 103 |
-
new_relations = kg_manager.create_relations(relations)
|
| 104 |
return json.dumps([{"from": r.from_entity, "to": r.to_entity, "relationType": r.relationType} for r in new_relations], indent=2)
|
| 105 |
|
| 106 |
-
def add_observations(
|
| 107 |
"""向知识图谱中已存在的实体添加新的观察记录。
|
| 108 |
|
| 109 |
Args:
|
| 110 |
-
|
| 111 |
|
| 112 |
Returns:
|
| 113 |
str: 表示成功添加的观察记录的JSON字符串。
|
| 114 |
"""
|
| 115 |
-
results = kg_manager.add_observations(observations)
|
| 116 |
return json.dumps(results, indent=2)
|
| 117 |
|
| 118 |
-
def delete_entities(
|
| 119 |
"""从知识图谱中删除多个实体及其相关联的关系。
|
| 120 |
|
| 121 |
Args:
|
| 122 |
-
|
| 123 |
|
| 124 |
Returns:
|
| 125 |
str: 表示操作成功的消息。
|
| 126 |
"""
|
| 127 |
-
|
|
|
|
| 128 |
return "Entities and their relations deleted successfully."
|
| 129 |
|
| 130 |
-
def delete_observations(
|
| 131 |
"""从知识图谱中的实体删除特定的观察记录。
|
| 132 |
|
| 133 |
Args:
|
| 134 |
-
|
| 135 |
|
| 136 |
Returns:
|
| 137 |
str: 表示操作成功的消息。
|
| 138 |
"""
|
| 139 |
-
kg_manager.delete_observations(deletions)
|
| 140 |
return "Observations deleted successfully."
|
| 141 |
|
| 142 |
-
def delete_relations(
|
| 143 |
"""从知识图谱中删除多个关系。
|
| 144 |
|
| 145 |
Args:
|
| 146 |
-
|
| 147 |
|
| 148 |
Returns:
|
| 149 |
str: 表示操作成功的消息。
|
| 150 |
"""
|
| 151 |
-
kg_manager.delete_relations(relations)
|
| 152 |
return "Relations deleted successfully."
|
| 153 |
|
| 154 |
def read_graph() -> Dict:
|
| 155 |
-
"""读取并返回整个知识图谱。
|
| 156 |
|
| 157 |
Returns:
|
| 158 |
Dict: 包含 'entities' 和 'relations' 列表的整个知识图谱。
|
| 159 |
"""
|
| 160 |
return kg_manager.read_graph()
|
| 161 |
|
| 162 |
-
def search_nodes(
|
| 163 |
"""根据查询词在知识图谱中搜索节点。
|
| 164 |
|
| 165 |
Args:
|
| 166 |
-
|
| 167 |
|
| 168 |
Returns:
|
| 169 |
Dict: 包含匹配的实体和它们之间关系的过滤后的知识图谱。
|
| 170 |
"""
|
| 171 |
-
return kg_manager.search_nodes(query)
|
| 172 |
|
| 173 |
-
def open_nodes(
|
| 174 |
"""通过名称打开知识图谱中的特定节点。
|
| 175 |
|
| 176 |
Args:
|
| 177 |
-
|
| 178 |
|
| 179 |
Returns:
|
| 180 |
Dict: 包含指定的实体和它们之间关系的过滤后的知识图谱。
|
| 181 |
"""
|
| 182 |
-
return kg_manager.open_nodes(names)
|
| 183 |
|
| 184 |
# --- 3. Gradio Headless 应用构建与 API 注册 ---
|
| 185 |
with gr.Blocks() as app:
|
| 186 |
-
# 我们不需要任何可见的UI组件,因为这个服务只给AI使用。
|
| 187 |
-
# 我们只需要一种方法来将我们的函数注册为API端点。
|
| 188 |
-
# 最干净的方法是使用 gr.load_api() 来定义API,但这需要更复杂的设置。
|
| 189 |
-
# 一个更简单、同样有效的方法是创建隐藏的组件来挂载API。
|
| 190 |
-
|
| 191 |
gr.Markdown("MCP Server is running. This UI is intentionally blank.", visible=True)
|
| 192 |
|
| 193 |
-
# 创建一组隐藏的组件,仅用于挂载我们的API函数
|
| 194 |
-
# 这些组件对用户不可见,但能让我们使用 .click() 和 api_name
|
| 195 |
with gr.Row(visible=False):
|
| 196 |
-
# 定义一个
|
|
|
|
|
|
|
|
|
|
|
|
|
| 197 |
dummy_btn = gr.Button()
|
| 198 |
-
|
| 199 |
-
|
| 200 |
-
|
| 201 |
-
|
| 202 |
-
|
| 203 |
-
|
| 204 |
-
|
| 205 |
-
|
| 206 |
-
|
| 207 |
-
|
| 208 |
-
|
| 209 |
-
dummy_btn.click(fn=create_entities, inputs=dict_list_input, outputs=str_output, api_name="create_entities")
|
| 210 |
-
dummy_btn.click(fn=create_relations, inputs=dict_list_input, outputs=str_output, api_name="create_relations")
|
| 211 |
-
dummy_btn.click(fn=add_observations, inputs=dict_list_input, outputs=str_output, api_name="add_observations")
|
| 212 |
-
dummy_btn.click(fn=delete_entities, inputs=str_list_input, outputs=str_output, api_name="delete_entities")
|
| 213 |
-
dummy_btn.click(fn=delete_observations, inputs=dict_list_input, outputs=str_output, api_name="delete_observations")
|
| 214 |
-
dummy_btn.click(fn=delete_relations, inputs=dict_list_input, outputs=str_output, api_name="delete_relations")
|
| 215 |
-
dummy_btn.click(fn=read_graph, inputs=None, outputs=json_output, api_name="read_graph")
|
| 216 |
-
dummy_btn.click(fn=search_nodes, inputs=str_input, outputs=json_output, api_name="search_nodes")
|
| 217 |
-
dummy_btn.click(fn=open_nodes, inputs=str_list_input, outputs=json_output, api_name="open_nodes")
|
| 218 |
|
| 219 |
if __name__ == "__main__":
|
| 220 |
app.launch(mcp_server=True)
|
|
|
|
| 20 |
relations: List[Relation] = field(default_factory=list)
|
| 21 |
|
| 22 |
class KnowledgeGraphManager:
|
| 23 |
+
# ... (Manager 的所有内部方法保持不变) ...
|
| 24 |
def __init__(self):
|
| 25 |
self.graph = KnowledgeGraph()
|
| 26 |
print("Initialized a new, empty in-memory knowledge graph.")
|
|
|
|
| 27 |
def create_entities(self, entities_data: List[Dict]) -> List[Entity]:
|
| 28 |
new_entities = []
|
| 29 |
for e_data in entities_data:
|
|
|
|
| 75 |
|
| 76 |
kg_manager = KnowledgeGraphManager()
|
| 77 |
|
| 78 |
+
# --- 2. API 工具函数定义 (修改了函数签名和文档) ---
|
| 79 |
+
def create_entities(payload: Dict) -> str:
|
|
|
|
|
|
|
|
|
|
| 80 |
"""在知识图谱中创建多个新实体。
|
| 81 |
|
| 82 |
Args:
|
| 83 |
+
payload (Dict): 一个包含'entities'键的JSON对象。'entities'的值是一个实体对象的列表。
|
| 84 |
|
| 85 |
Returns:
|
| 86 |
str: 表示成功创建的新实体的JSON字符串。
|
| 87 |
"""
|
| 88 |
+
new_entities = kg_manager.create_entities(payload['entities'])
|
| 89 |
return json.dumps([asdict(e) for e in new_entities], indent=2)
|
| 90 |
|
| 91 |
+
def create_relations(payload: Dict) -> str:
|
| 92 |
+
"""在知识图谱中的实体之间创建多个新关系。
|
| 93 |
|
| 94 |
Args:
|
| 95 |
+
payload (Dict): 一个包含'relations'键的JSON对象。'relations'的值是一个关系对象的列表。
|
| 96 |
|
| 97 |
Returns:
|
| 98 |
str: 表示成功创建的新关系的JSON字符串。
|
| 99 |
"""
|
| 100 |
+
new_relations = kg_manager.create_relations(payload['relations'])
|
| 101 |
return json.dumps([{"from": r.from_entity, "to": r.to_entity, "relationType": r.relationType} for r in new_relations], indent=2)
|
| 102 |
|
| 103 |
+
def add_observations(payload: Dict) -> str:
|
| 104 |
"""向知识图谱中已存在的实体添加新的观察记录。
|
| 105 |
|
| 106 |
Args:
|
| 107 |
+
payload (Dict): 一个包含'observations'键的JSON对象。'observations'的值是一个观察记录对象的列表。
|
| 108 |
|
| 109 |
Returns:
|
| 110 |
str: 表示成功添加的观察记录的JSON字符串。
|
| 111 |
"""
|
| 112 |
+
results = kg_manager.add_observations(payload['observations'])
|
| 113 |
return json.dumps(results, indent=2)
|
| 114 |
|
| 115 |
+
def delete_entities(payload: Dict) -> str:
|
| 116 |
"""从知识图谱中删除多个实体及其相关联的关系。
|
| 117 |
|
| 118 |
Args:
|
| 119 |
+
payload (Dict): 一个包含'entityNames'键的JSON对象。'entityNames'的值是一个实体名称的列表。
|
| 120 |
|
| 121 |
Returns:
|
| 122 |
str: 表示操作成功的消息。
|
| 123 |
"""
|
| 124 |
+
|
| 125 |
+
kg_manager.delete_entities(payload['entityNames'])
|
| 126 |
return "Entities and their relations deleted successfully."
|
| 127 |
|
| 128 |
+
def delete_observations(payload: Dict) -> str:
|
| 129 |
"""从知识图谱中的实体删除特定的观察记录。
|
| 130 |
|
| 131 |
Args:
|
| 132 |
+
payload (Dict): 一个包含'deletions'键的JSON对象。'deletions'的值是一个删除指令的列表。
|
| 133 |
|
| 134 |
Returns:
|
| 135 |
str: 表示操作成功的消息。
|
| 136 |
"""
|
| 137 |
+
kg_manager.delete_observations(payload['deletions'])
|
| 138 |
return "Observations deleted successfully."
|
| 139 |
|
| 140 |
+
def delete_relations(payload: Dict) -> str:
|
| 141 |
"""从知识图谱中删除多个关系。
|
| 142 |
|
| 143 |
Args:
|
| 144 |
+
payload (Dict): 一个包含'relations'键的JSON对象。'relations'的值是一个要删除的关系对象的列表。
|
| 145 |
|
| 146 |
Returns:
|
| 147 |
str: 表示操作成功的消息。
|
| 148 |
"""
|
| 149 |
+
kg_manager.delete_relations(payload['relations'])
|
| 150 |
return "Relations deleted successfully."
|
| 151 |
|
| 152 |
def read_graph() -> Dict:
|
| 153 |
+
"""读取并返回整个知识图谱。此函数不需要参数。
|
| 154 |
|
| 155 |
Returns:
|
| 156 |
Dict: 包含 'entities' 和 'relations' 列表的整个知识图谱。
|
| 157 |
"""
|
| 158 |
return kg_manager.read_graph()
|
| 159 |
|
| 160 |
+
def search_nodes(payload: Dict) -> Dict:
|
| 161 |
"""根据查询词在知识图谱中搜索节点。
|
| 162 |
|
| 163 |
Args:
|
| 164 |
+
payload (Dict): 一个包含'query'键的JSON对象。'query'的值是用于搜索的字符串。
|
| 165 |
|
| 166 |
Returns:
|
| 167 |
Dict: 包含匹配的实体和它们之间关系的过滤后的知识图谱。
|
| 168 |
"""
|
| 169 |
+
return kg_manager.search_nodes(payload['query'])
|
| 170 |
|
| 171 |
+
def open_nodes(payload: Dict) -> Dict:
|
| 172 |
"""通过名称打开知识图谱中的特定节点。
|
| 173 |
|
| 174 |
Args:
|
| 175 |
+
payload (Dict): 一个包含'names'键的JSON对象。'names'的值是一个要检索的实体名称的列表。
|
| 176 |
|
| 177 |
Returns:
|
| 178 |
Dict: 包含指定的实体和它们之间关系的过滤后的知识图谱。
|
| 179 |
"""
|
| 180 |
+
return kg_manager.open_nodes(payload['names'])
|
| 181 |
|
| 182 |
# --- 3. Gradio Headless 应用构建与 API 注册 ---
|
| 183 |
with gr.Blocks() as app:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 184 |
gr.Markdown("MCP Server is running. This UI is intentionally blank.", visible=True)
|
| 185 |
|
|
|
|
|
|
|
| 186 |
with gr.Row(visible=False):
|
| 187 |
+
# 定义一个统一的输入组件,因为所有函数现在都接收一个JSON对象
|
| 188 |
+
json_input = gr.JSON(value={})
|
| 189 |
+
# 定义一个统一的输出组件,因为输出总是JSON兼容的
|
| 190 |
+
generic_output = gr.JSON()
|
| 191 |
+
# 定义一个按钮作为所有API的挂载点
|
| 192 |
dummy_btn = gr.Button()
|
| 193 |
+
|
| 194 |
+
# 将我们的 9 个函数绑定到虚拟按钮上
|
| 195 |
+
dummy_btn.click(fn=create_entities, inputs=json_input, outputs=generic_output, api_name="create_entities")
|
| 196 |
+
dummy_btn.click(fn=create_relations, inputs=json_input, outputs=generic_output, api_name="create_relations")
|
| 197 |
+
dummy_btn.click(fn=add_observations, inputs=json_input, outputs=generic_output, api_name="add_observations")
|
| 198 |
+
dummy_btn.click(fn=delete_entities, inputs=json_input, outputs=generic_output, api_name="delete_entities")
|
| 199 |
+
dummy_btn.click(fn=delete_observations, inputs=json_input, outputs=generic_output, api_name="delete_observations")
|
| 200 |
+
dummy_btn.click(fn=delete_relations, inputs=json_input, outputs=generic_output, api_name="delete_relations")
|
| 201 |
+
dummy_btn.click(fn=read_graph, inputs=None, outputs=generic_output, api_name="read_graph")
|
| 202 |
+
dummy_btn.click(fn=search_nodes, inputs=json_input, outputs=generic_output, api_name="search_nodes")
|
| 203 |
+
dummy_btn.click(fn=open_nodes, inputs=json_input, outputs=generic_output, api_name="open_nodes")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 204 |
|
| 205 |
if __name__ == "__main__":
|
| 206 |
app.launch(mcp_server=True)
|