通过BAML和Neo4j实现图形数据的结构化转化

2024年12月04日 由 alex 发表 22 0

BAML 是 Boundary 创建的一种语言,用于从无结构数据中生成干净、结构化的输出。Neo4j 是一种图形数据库,用于将数据以图形的方式存储——即节点及它们之间的关系。


在本文中,我将介绍如何扩展 BAML 的一个示例项目,将网页转换为图形表示,以快速填充 Neo4j 实例。


要求

  • 安装 BAML 命令行界面 (CLI)
  • 活跃的 Neo4j 数据库


工作流程


2


FastAPI

Boundary 提供了使用 BAML 从硬编码的简历中提取数据的简单 FastAPI 服务器示例代码。FastAPI 是一个很棒的框架,它包含一个交互式文档页面,允许你直接从浏览器中测试端点。


我最初对这个示例进行了分叉,并添加了一个实验性端点,用于从网页内容中提取实体和关系。这个端点接受一个 URL 字符串列表作为参数。


底层函数将调用 BAML 函数,从网页中提取数据,并将这些数据作为结构化 JSON 对象上传到 Neo4j 中。


@app.post("/url_to_graph")
async def extract_url_content(urls: list[str]):
    """General purpose conversion of contents from a list of urls to a graph"""
    
    # 1. Prep html to text conversion
    h = html2text.HTML2Text()
    h.ignore_links = False
    # 2. Extract text from each url
    markdown_contents = []
    for url in urls:
        try:
            response = requests.get(url)
            response.raise_for_status()
            html_content = response.text
            markdown_content = h.handle(html_content)
            markdown_contents.append(markdown_content)
        except Exception as e:
            markdown_contents.append(f"Error processing {url}: {str(e)}")
    # 3. Composite the text 
    combined_markdown = "\n\n".join(markdown_contents)
    # 4. Run BAML to get a Cytoscape graph JSON representation of text
    json_output = b.GenerateCytoscapeGraph(combined_markdown)
    json_str = str(json_output.model_dump_json())
    json_dict = json.loads(json_str)
    # 5. Upload the JSON data to Neo4j
    finished = upload_cytoscape_to_neo4j(json_dict)
    return {"finished": finished}


BAML

在结构上,当使用 BAML 时,会在根项目文件夹下添加两个子文件夹:baml_src 和 baml_client。


3


baml_client 文件夹中的内容是由活动的 VS Code 插件自动生成的,或者在更新 baml_src 文件夹中的任何 .baml 文件后,通过手动运行 baml cli generate 命令生成的。


baml_src 文件夹需要包含 main.baml 和 clients.baml 文件。clients.baml 文件包含了要使用的基础模型的规格说明,而 main.baml 文件则指定了配置选项。


4


注意:此处的版本号应与 CLI 版本相匹配,否则自动生成的 baml-client 内容将停止工作。


你添加的 .baml 文件将包含以下三个元素中的一个或多个,或全部三个:

  • 模型规格说明(必需)
  • 函数(必需)
  • 测试(可选)


BAML 函数是指定输入到输出定义、要使用的客户端模型以及 LLM(可能是指大型语言模型,Large Language Model)提示的地方。以下是 FastAPI 端点调用的函数,用于将 HTML 文本转换为结构化的图形数据。


5


模型类的定义方式与 Pydantic 类似,但更为简洁,而 Pydantic 是在其底层使用的。为了获得如下所示的结构化 JSON 输出:


  {{
      "elements": {
        "nodes": [
          {
            "data": {
              "id": "neo4j_graph_database",
              "name": "Neo4j Graph Database",
              "label": "product",
              "description": "Self or fully-managed, deploy anywhere"
            }
          },
          {
            "data": {
              "id": "neo4j_auradb",
              "name": "Neo4j AuraDB",
              "label": "product",
              "description": "Fully-managed graph database as a service"
            }
          },
        ],
        "edges": [
          {
            "data": {
              "id": "edge_1",
              "source": "neo4j_graph_database",
              "target": "neo4j_auradb",
              "label": "RELATED_TO"
            }
          }
        ]
      }
    }


以下是在 BAML 中可以使用的模型定义:


6


注意:目前,即使在不同的 .baml 文件中定义,BAML 的类和函数名也是全局范围的。此外,属性名称中目前不允许使用下划线前缀(例如:_id)。


Cytoscape


7


Cytoscape 是一个流行的开源平台,用于可视化图形(或网络)数据。它使用的 JSON 数据格式既简单又足够灵活,除了节点必需的 id 和 label 属性外,还支持其他附加数据。


Neo4j

Neo4j 是最受欢迎的图形数据库之一。它原生地使用 Cypher 查询语言来输入、操作和输出图形数据。因此,在这个演示中,我使用了官方支持的 neo4j bolt Python 包,在 cytoscape2neo4j.py 文件中上传 Cytoscape 格式的 JSON 数据。


upload_cytoscape_to_neo4j 函数。该函数会遍历源 JSON 数据中定义的每个节点和关系,并创建一个 Cypher 查询来为每个指定的节点创建一个节点,并为每个指定的边创建一个关系。


使用对象图形映射器(OGM)包(如 Neomodel)或设置 Apollo GraphQL 服务器是创建 JSON 和 Neo4j 之间输入桥梁的替代方法。


运行

完整的应用程序可以在这个公开的 Github 仓库中找到。按照安装和运行说明操作后,应该可以在任何浏览器的 localhost:8000/docs 上访问以下交互式文档。


8


还有一些其他实验性的端点,但本文讨论的是 /url_to_graph 选项。


要进行测试,请打开端点详细信息,点击“Try It Out(试用)”按钮,输入一个或多个有效的网页URL,然后点击“Execute(执行)”。


9


过一会儿,根据源网页的数量和大小,你有望得到一个 finished:true 的响应。


10


并且,在终端/控制台中,你应该会看到类似这样的内容:


   ...
    ---Parsed Response (class CytoscapeJSON)---Parsed Response (class CytoscapeJSON)---
    {
      "elements": {
        "nodes": [
          {
            "data": {
              "id": "neo4j_graph_database",
              "name": "Neo4j Graph Database",
              "label": "product",
              "description": "Self or fully-managed, deploy anywhere"
            }
          },
          {
            "data": {
              "id": "neo4j_auradb",
              "name": "Neo4j AuraDB",
              "label": "product",
              "description": "Fully-managed graph database as a service"
            }
          },
          {
            "data": {
              "id": "generative_ai",
              "name": "Generative AI",
              "label": "use_case",
              "description": "Back your LLMs with a knowledge graph for better business AI"
            }
          }
        ],
        "edges": [
          {
            "data": {
              "id": "prod_use_case_1",
              "source": "neo4j_graph_database",
              "target": "generative_ai",
              "label": "ENABLED_BY"
            }
          },
          {
            "data": {
              "id": "prod_use_case_2",
              "source": "neo4j_auradb",
              "target": "generative_ai",
              "label": "ENABLED_BY"
            }
          }
        ]
      }
    }
INFO:     127.0.0.1:63190 - "POST /url_to_graph HTTP/1.1" 200 OK


并且,在你的 Neo4j 控制台中,你应该会看到类似这样的内容:


11


文章来源:https://medium.com/@_jalakoo_/unstructured-to-structured-graph-data-using-baml-to-neo4j-c210d54a26cb
欢迎关注ATYUN官方公众号
商务合作及内容投稿请联系邮箱:bd@atyun.com
评论 登录
热门职位
Maluuba
20000~40000/月
Cisco
25000~30000/月 深圳市
PilotAILabs
30000~60000/年 深圳市
写评论取消
回复取消