cognee/notebooks/node_scores.ipynb
Boris e7644f4b3a
feat: migrate new UI to cognee (#966)
<!-- .github/pull_request_template.md -->

## Description
<!-- Provide a clear description of the changes in this PR -->

## DCO Affirmation
I affirm that all code in every commit of this pull request conforms to
the terms of the Topoteretes Developer Certificate of Origin.

---------

Co-authored-by: Igor Ilic <igorilic03@gmail.com>
2025-06-18 20:56:44 +02:00

686 lines
72 KiB
Text
Vendored

{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"id": "fb1fc4002c4652fc",
"metadata": {
"ExecuteTime": {
"end_time": "2025-04-22T20:11:34.191932Z",
"start_time": "2025-04-22T20:11:28.743188Z"
}
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"\n",
"\u001b[2m2025-06-18T18:22:18.419562\u001b[0m [\u001b[32m\u001b[1minfo \u001b[0m] \u001b[1mDeleted old log file: /Users/borisarzentar/Projects/Topoteretes/cognee/logs/2025-06-18_20-05-03.log\u001b[0m [\u001b[0m\u001b[1m\u001b[34mcognee.shared.logging_utils\u001b[0m]\u001b[0m\n",
"\n",
"\u001b[2m2025-06-18T18:22:18.420076\u001b[0m [\u001b[32m\u001b[1minfo \u001b[0m] \u001b[1mLogging initialized \u001b[0m [\u001b[0m\u001b[1m\u001b[34mcognee.shared.logging_utils\u001b[0m]\u001b[0m \u001b[36mcognee_version\u001b[0m=\u001b[35m0.1.42-dev\u001b[0m \u001b[36mos_info\u001b[0m=\u001b[35m'Darwin 24.5.0 (Darwin Kernel Version 24.5.0: Tue Apr 22 19:54:25 PDT 2025; root:xnu-11417.121.6~2/RELEASE_ARM64_T6020)'\u001b[0m \u001b[36mpython_version\u001b[0m=\u001b[35m3.11.5\u001b[0m \u001b[36mstructlog_version\u001b[0m=\u001b[35m25.4.0\u001b[0m\n",
"\n",
"\u001b[1mHTTP Request: GET https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json \"HTTP/1.1 200 OK\"\u001b[0m\n",
"/Users/borisarzentar/Projects/Topoteretes/cognee/.venv/lib/python3.11/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n",
" from .autonotebook import tqdm as notebook_tqdm\n",
"/Users/borisarzentar/Projects/Topoteretes/cognee/.venv/lib/python3.11/site-packages/dlt/helpers/dbt/__init__.py:3: UserWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html. The pkg_resources package is slated for removal as early as 2025-11-30. Refrain from using this package or pin to Setuptools<81.\n",
" import pkg_resources\n"
]
}
],
"source": [
"import cognee"
]
},
{
"cell_type": "markdown",
"id": "6c18de8dad96c3f8",
"metadata": {},
"source": [
"# Basic setup"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "initial_id",
"metadata": {
"ExecuteTime": {
"end_time": "2025-04-22T20:11:04.996737Z",
"start_time": "2025-04-22T20:11:04.992873Z"
},
"collapsed": true
},
"outputs": [],
"source": [
"# cognee knowledge graph will be created based on this text\n",
"text = \"\"\"\n",
"Natural language processing (NLP) is an interdisciplinary\n",
"subfield of computer science and information retrieval.\n",
"\"\"\""
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "a2989b7d8237bd7d",
"metadata": {
"ExecuteTime": {
"end_time": "2025-04-22T20:13:18.624544Z",
"start_time": "2025-04-22T20:13:15.107863Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Adding text to cognee:\n",
"Natural language processing (NLP) is an interdisciplinary\n",
"subfield of computer science and information retrieval.\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"\n",
"\u001b[1mLangfuse client is disabled since no public_key was provided as a parameter or environment variable 'LANGFUSE_PUBLIC_KEY'. See our docs: https://langfuse.com/docs/sdk/python/low-level-sdk#initialize-client\u001b[0m\u001b[92m20:22:22 - LiteLLM:INFO\u001b[0m: utils.py:3101 - \n",
"LiteLLM completion() model= gpt-4o-mini; provider = openai\n",
"\u001b[1m\n",
"LiteLLM completion() model= gpt-4o-mini; provider = openai\u001b[0m\u001b[92m20:22:23 - LiteLLM:INFO\u001b[0m: cost_calculator.py:655 - selected model name for cost calculation: openai/gpt-4o-mini-2024-07-18\n",
"\u001b[1mselected model name for cost calculation: openai/gpt-4o-mini-2024-07-18\u001b[0m\n",
"\u001b[1mEmbeddingRateLimiter initialized: enabled=False, requests_limit=60, interval_seconds=60\u001b[0m\u001b[92m20:22:23 - LiteLLM:INFO\u001b[0m: cost_calculator.py:655 - selected model name for cost calculation: openai/gpt-4o-mini-2024-07-18\n",
"\u001b[1mselected model name for cost calculation: openai/gpt-4o-mini-2024-07-18\u001b[0m\u001b[92m20:22:24 - LiteLLM:INFO\u001b[0m: cost_calculator.py:655 - selected model name for cost calculation: openai/text-embedding-3-large\n",
"\u001b[1mselected model name for cost calculation: openai/text-embedding-3-large\u001b[0m\n",
"\u001b[2m2025-06-18T18:22:24.068461\u001b[0m [\u001b[32m\u001b[1minfo \u001b[0m] \u001b[1mPipeline run started: `9ba851a9-f173-544b-a219-ac0af2f657ff`\u001b[0m [\u001b[0m\u001b[1m\u001b[34mrun_tasks(tasks: [Task], data)\u001b[0m]\u001b[0m\n",
"\u001b[2m2025-06-18T18:22:24.068921\u001b[0m [\u001b[32m\u001b[1minfo \u001b[0m] \u001b[1mCoroutine task started: `resolve_data_directories`\u001b[0m [\u001b[0m\u001b[1m\u001b[34mrun_tasks_base\u001b[0m]\u001b[0m\n",
"\u001b[2m2025-06-18T18:22:24.069781\u001b[0m [\u001b[32m\u001b[1minfo \u001b[0m] \u001b[1mCoroutine task started: `ingest_data`\u001b[0m [\u001b[0m\u001b[1m\u001b[34mrun_tasks_base\u001b[0m]\u001b[0m"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"User 769fc99f-cb9b-4d3b-b4ef-c81aea922b27 has registered.\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"\n",
"\u001b[2m2025-06-18T18:22:24.550667\u001b[0m [\u001b[32m\u001b[1minfo \u001b[0m] \u001b[1mCoroutine task completed: `ingest_data`\u001b[0m [\u001b[0m\u001b[1m\u001b[34mrun_tasks_base\u001b[0m]\u001b[0m\n",
"\u001b[2m2025-06-18T18:22:24.551277\u001b[0m [\u001b[32m\u001b[1minfo \u001b[0m] \u001b[1mCoroutine task completed: `resolve_data_directories`\u001b[0m [\u001b[0m\u001b[1m\u001b[34mrun_tasks_base\u001b[0m]\u001b[0m\n",
"\u001b[2m2025-06-18T18:22:24.551779\u001b[0m [\u001b[32m\u001b[1minfo \u001b[0m] \u001b[1mPipeline run completed: `9ba851a9-f173-544b-a219-ac0af2f657ff`\u001b[0m [\u001b[0m\u001b[1m\u001b[34mrun_tasks(tasks: [Task], data)\u001b[0m]\u001b[0m"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Text added successfully.\n",
"\n"
]
}
],
"source": [
"print(\"Adding text to cognee:\")\n",
"print(text.strip())\n",
"# Add the text, and make it available for cognify\n",
"await cognee.add(text)\n",
"print(\"Text added successfully.\\n\")"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "3034ec43e0339d72",
"metadata": {
"ExecuteTime": {
"end_time": "2025-04-22T20:13:46.162905Z",
"start_time": "2025-04-22T20:13:27.466606Z"
}
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"\n",
"\u001b[2m2025-06-18T18:22:24.559363\u001b[0m [\u001b[32m\u001b[1minfo \u001b[0m] \u001b[1mOntology file 'None' not found. No owl ontology will be attached to the graph.\u001b[0m [\u001b[0m\u001b[1m\u001b[34mOntologyAdapter\u001b[0m]\u001b[0m\n",
"\u001b[2m2025-06-18T18:22:24.571809\u001b[0m [\u001b[32m\u001b[1minfo \u001b[0m] \u001b[1mPipeline run started: `8e988ccd-913a-5633-8ccb-e025246f9b94`\u001b[0m [\u001b[0m\u001b[1m\u001b[34mrun_tasks(tasks: [Task], data)\u001b[0m]\u001b[0m\n",
"\u001b[2m2025-06-18T18:22:24.572555\u001b[0m [\u001b[32m\u001b[1minfo \u001b[0m] \u001b[1mCoroutine task started: `classify_documents`\u001b[0m [\u001b[0m\u001b[1m\u001b[34mrun_tasks_base\u001b[0m]\u001b[0m\n",
"\u001b[2m2025-06-18T18:22:24.572990\u001b[0m [\u001b[32m\u001b[1minfo \u001b[0m] \u001b[1mCoroutine task started: `check_permissions_on_dataset`\u001b[0m [\u001b[0m\u001b[1m\u001b[34mrun_tasks_base\u001b[0m]\u001b[0m\n",
"\u001b[2m2025-06-18T18:22:24.577489\u001b[0m [\u001b[32m\u001b[1minfo \u001b[0m] \u001b[1mAsync Generator task started: `extract_chunks_from_documents`\u001b[0m [\u001b[0m\u001b[1m\u001b[34mrun_tasks_base\u001b[0m]\u001b[0m\n",
"\u001b[2m2025-06-18T18:22:24.580717\u001b[0m [\u001b[32m\u001b[1minfo \u001b[0m] \u001b[1mCoroutine task started: `extract_graph_from_data`\u001b[0m [\u001b[0m\u001b[1m\u001b[34mrun_tasks_base\u001b[0m]\u001b[0m\u001b[92m20:22:24 - LiteLLM:INFO\u001b[0m: utils.py:3101 - \n",
"LiteLLM completion() model= gpt-4o-mini; provider = openai\n",
"\u001b[1m\n",
"LiteLLM completion() model= gpt-4o-mini; provider = openai\u001b[0m\u001b[92m20:22:27 - LiteLLM:INFO\u001b[0m: cost_calculator.py:655 - selected model name for cost calculation: openai/gpt-4o-mini-2024-07-18\n",
"\u001b[1mselected model name for cost calculation: openai/gpt-4o-mini-2024-07-18\u001b[0m\u001b[92m20:22:27 - LiteLLM:INFO\u001b[0m: cost_calculator.py:655 - selected model name for cost calculation: openai/gpt-4o-mini-2024-07-18\n",
"\u001b[1mselected model name for cost calculation: openai/gpt-4o-mini-2024-07-18\u001b[0m\n",
"\u001b[2m2025-06-18T18:22:27.425691\u001b[0m [\u001b[32m\u001b[1minfo \u001b[0m] \u001b[1mNo close match found for 'concept' in category 'classes'\u001b[0m [\u001b[0m\u001b[1m\u001b[34mOntologyAdapter\u001b[0m]\u001b[0m\n",
"\u001b[2m2025-06-18T18:22:27.426182\u001b[0m [\u001b[32m\u001b[1minfo \u001b[0m] \u001b[1mNo close match found for 'natural language processing' in category 'individuals'\u001b[0m [\u001b[0m\u001b[1m\u001b[34mOntologyAdapter\u001b[0m]\u001b[0m\n",
"\u001b[2m2025-06-18T18:22:27.426553\u001b[0m [\u001b[32m\u001b[1minfo \u001b[0m] \u001b[1mNo close match found for 'field' in category 'classes'\u001b[0m [\u001b[0m\u001b[1m\u001b[34mOntologyAdapter\u001b[0m]\u001b[0m\n",
"\u001b[2m2025-06-18T18:22:27.426814\u001b[0m [\u001b[32m\u001b[1minfo \u001b[0m] \u001b[1mNo close match found for 'computer science' in category 'individuals'\u001b[0m [\u001b[0m\u001b[1m\u001b[34mOntologyAdapter\u001b[0m]\u001b[0m\n",
"\u001b[2m2025-06-18T18:22:27.427082\u001b[0m [\u001b[32m\u001b[1minfo \u001b[0m] \u001b[1mNo close match found for 'information retrieval' in category 'individuals'\u001b[0m [\u001b[0m\u001b[1m\u001b[34mOntologyAdapter\u001b[0m]\u001b[0m\u001b[92m20:22:27 - LiteLLM:INFO\u001b[0m: cost_calculator.py:655 - selected model name for cost calculation: openai/text-embedding-3-large\n",
"\u001b[1mselected model name for cost calculation: openai/text-embedding-3-large\u001b[0m\u001b[92m20:22:28 - LiteLLM:INFO\u001b[0m: cost_calculator.py:655 - selected model name for cost calculation: openai/text-embedding-3-large\n",
"\u001b[1mselected model name for cost calculation: openai/text-embedding-3-large\u001b[0m\u001b[92m20:22:28 - LiteLLM:INFO\u001b[0m: cost_calculator.py:655 - selected model name for cost calculation: openai/text-embedding-3-large\n",
"\u001b[1mselected model name for cost calculation: openai/text-embedding-3-large\u001b[0m\u001b[92m20:22:29 - LiteLLM:INFO\u001b[0m: cost_calculator.py:655 - selected model name for cost calculation: openai/text-embedding-3-large\n",
"\u001b[1mselected model name for cost calculation: openai/text-embedding-3-large\u001b[0m\u001b[92m20:22:30 - LiteLLM:INFO\u001b[0m: cost_calculator.py:655 - selected model name for cost calculation: openai/text-embedding-3-large\n",
"\u001b[1mselected model name for cost calculation: openai/text-embedding-3-large\u001b[0m\n",
"\u001b[2m2025-06-18T18:22:30.877815\u001b[0m [\u001b[32m\u001b[1minfo \u001b[0m] \u001b[1mCoroutine task started: `summarize_text`\u001b[0m [\u001b[0m\u001b[1m\u001b[34mrun_tasks_base\u001b[0m]\u001b[0m\u001b[92m20:22:30 - LiteLLM:INFO\u001b[0m: utils.py:3101 - \n",
"LiteLLM completion() model= gpt-4o-mini; provider = openai\n",
"\u001b[1m\n",
"LiteLLM completion() model= gpt-4o-mini; provider = openai\u001b[0m\u001b[92m20:22:32 - LiteLLM:INFO\u001b[0m: cost_calculator.py:655 - selected model name for cost calculation: openai/gpt-4o-mini-2024-07-18\n",
"\u001b[1mselected model name for cost calculation: openai/gpt-4o-mini-2024-07-18\u001b[0m\u001b[92m20:22:32 - LiteLLM:INFO\u001b[0m: cost_calculator.py:655 - selected model name for cost calculation: openai/gpt-4o-mini-2024-07-18\n",
"\u001b[1mselected model name for cost calculation: openai/gpt-4o-mini-2024-07-18\u001b[0m\n",
"\u001b[2m2025-06-18T18:22:32.124629\u001b[0m [\u001b[32m\u001b[1minfo \u001b[0m] \u001b[1mCoroutine task started: `add_data_points`\u001b[0m [\u001b[0m\u001b[1m\u001b[34mrun_tasks_base\u001b[0m]\u001b[0m\u001b[92m20:22:32 - LiteLLM:INFO\u001b[0m: cost_calculator.py:655 - selected model name for cost calculation: openai/text-embedding-3-large\n",
"\u001b[1mselected model name for cost calculation: openai/text-embedding-3-large\u001b[0m\u001b[92m20:22:32 - LiteLLM:INFO\u001b[0m: cost_calculator.py:655 - selected model name for cost calculation: openai/text-embedding-3-large\n",
"\u001b[1mselected model name for cost calculation: openai/text-embedding-3-large\u001b[0m\u001b[92m20:22:33 - LiteLLM:INFO\u001b[0m: cost_calculator.py:655 - selected model name for cost calculation: openai/text-embedding-3-large\n",
"\u001b[1mselected model name for cost calculation: openai/text-embedding-3-large\u001b[0m\u001b[92m20:22:33 - LiteLLM:INFO\u001b[0m: cost_calculator.py:655 - selected model name for cost calculation: openai/text-embedding-3-large\n",
"\u001b[1mselected model name for cost calculation: openai/text-embedding-3-large\u001b[0m\u001b[92m20:22:34 - LiteLLM:INFO\u001b[0m: cost_calculator.py:655 - selected model name for cost calculation: openai/text-embedding-3-large\n",
"\u001b[1mselected model name for cost calculation: openai/text-embedding-3-large\u001b[0m\u001b[92m20:22:34 - LiteLLM:INFO\u001b[0m: cost_calculator.py:655 - selected model name for cost calculation: openai/text-embedding-3-large\n",
"\u001b[1mselected model name for cost calculation: openai/text-embedding-3-large\u001b[0m\n",
"\u001b[2m2025-06-18T18:22:34.702737\u001b[0m [\u001b[32m\u001b[1minfo \u001b[0m] \u001b[1mCoroutine task completed: `add_data_points`\u001b[0m [\u001b[0m\u001b[1m\u001b[34mrun_tasks_base\u001b[0m]\u001b[0m\n",
"\u001b[2m2025-06-18T18:22:34.703250\u001b[0m [\u001b[32m\u001b[1minfo \u001b[0m] \u001b[1mCoroutine task completed: `summarize_text`\u001b[0m [\u001b[0m\u001b[1m\u001b[34mrun_tasks_base\u001b[0m]\u001b[0m\n",
"\u001b[2m2025-06-18T18:22:34.703582\u001b[0m [\u001b[32m\u001b[1minfo \u001b[0m] \u001b[1mCoroutine task completed: `extract_graph_from_data`\u001b[0m [\u001b[0m\u001b[1m\u001b[34mrun_tasks_base\u001b[0m]\u001b[0m\n",
"\u001b[2m2025-06-18T18:22:34.703925\u001b[0m [\u001b[32m\u001b[1minfo \u001b[0m] \u001b[1mAsync Generator task completed: `extract_chunks_from_documents`\u001b[0m [\u001b[0m\u001b[1m\u001b[34mrun_tasks_base\u001b[0m]\u001b[0m\n",
"\u001b[2m2025-06-18T18:22:34.704270\u001b[0m [\u001b[32m\u001b[1minfo \u001b[0m] \u001b[1mCoroutine task completed: `check_permissions_on_dataset`\u001b[0m [\u001b[0m\u001b[1m\u001b[34mrun_tasks_base\u001b[0m]\u001b[0m\n",
"\u001b[2m2025-06-18T18:22:34.704635\u001b[0m [\u001b[32m\u001b[1minfo \u001b[0m] \u001b[1mCoroutine task completed: `classify_documents`\u001b[0m [\u001b[0m\u001b[1m\u001b[34mrun_tasks_base\u001b[0m]\u001b[0m\n",
"\u001b[2m2025-06-18T18:22:34.705024\u001b[0m [\u001b[32m\u001b[1minfo \u001b[0m] \u001b[1mPipeline run completed: `8e988ccd-913a-5633-8ccb-e025246f9b94`\u001b[0m [\u001b[0m\u001b[1m\u001b[34mrun_tasks(tasks: [Task], data)\u001b[0m]\u001b[0m"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Cognify process complete.\n",
"\n"
]
}
],
"source": [
"# Use LLMs and cognee to create knowledge graph\n",
"await cognee.cognify()\n",
"print(\"Cognify process complete.\\n\")"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "3144acc7a837e75a",
"metadata": {
"ExecuteTime": {
"end_time": "2025-04-22T20:15:01.401236Z",
"start_time": "2025-04-22T20:15:01.397148Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Searching cognee for insights with query: 'Tell me about NLP'\n"
]
}
],
"source": [
"query_text = \"Tell me about NLP\"\n",
"print(f\"Searching cognee for insights with query: '{query_text}'\")"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "3c3eba3dc338dda2",
"metadata": {
"ExecuteTime": {
"end_time": "2025-04-22T20:15:25.805Z",
"start_time": "2025-04-22T20:15:24.475476Z"
}
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"\u001b[92m20:22:35 - LiteLLM:INFO\u001b[0m: cost_calculator.py:655 - selected model name for cost calculation: openai/text-embedding-3-large\n",
"\u001b[1mselected model name for cost calculation: openai/text-embedding-3-large\u001b[0m\u001b[92m20:22:35 - LiteLLM:INFO\u001b[0m: cost_calculator.py:655 - selected model name for cost calculation: openai/text-embedding-3-large\n",
"\u001b[1mselected model name for cost calculation: openai/text-embedding-3-large\u001b[0m"
]
}
],
"source": [
"from cognee.api.v1.search import SearchType\n",
"\n",
"# Query cognee for insights on the added text\n",
"search_results = await cognee.search(query_type=SearchType.INSIGHTS, query_text=query_text)\n"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "3dd224c6791db5e0",
"metadata": {
"ExecuteTime": {
"end_time": "2025-04-22T20:15:48.466032Z",
"start_time": "2025-04-22T20:15:48.460739Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"({'id': 'bc338a39-64d6-549a-acec-da60846dd90d', 'name': 'natural language processing', 'type': 'Entity', 'created_at': 1750270947426, 'updated_at': 1750270947426, 'ontology_valid': False, 'version': 1, 'topological_rank': 0, 'metadata': {'index_fields': ['name']}, 'belongs_to_set': None, 'description': 'An interdisciplinary subfield of computer science and information retrieval.'}, {'relationship_name': 'contains', 'source_node_id': 'ec72faa8-a238-52f7-b159-81272937347e', 'target_node_id': 'bc338a39-64d6-549a-acec-da60846dd90d', 'updated_at': '2025-06-18 18:22:32'}, {'id': 'ec72faa8-a238-52f7-b159-81272937347e', 'name': '', 'type': 'DocumentChunk', 'created_at': 1750270944579, 'updated_at': 1750270944579, 'ontology_valid': False, 'version': 1, 'topological_rank': 0, 'metadata': {'index_fields': ['text']}, 'belongs_to_set': None, 'text': '\\nNatural language processing (NLP) is an interdisciplinary\\nsubfield of computer science and information retrieval.\\n', 'chunk_size': 36, 'chunk_index': 0, 'cut_type': 'paragraph_end'})\n",
"({'id': 'bc338a39-64d6-549a-acec-da60846dd90d', 'name': 'natural language processing', 'type': 'Entity', 'created_at': 1750270947426, 'updated_at': 1750270947426, 'ontology_valid': False, 'version': 1, 'topological_rank': 0, 'metadata': {'index_fields': ['name']}, 'belongs_to_set': None, 'description': 'An interdisciplinary subfield of computer science and information retrieval.'}, {'relationship_name': 'is_related_to', 'source_node_id': 'bc338a39-64d6-549a-acec-da60846dd90d', 'target_node_id': '02bdab9a-0981-518c-a0d4-1684e0329447', 'ontology_valid': False}, {'id': '02bdab9a-0981-518c-a0d4-1684e0329447', 'name': 'information retrieval', 'type': 'Entity', 'created_at': 1750270947427, 'updated_at': 1750270947427, 'ontology_valid': False, 'version': 1, 'topological_rank': 0, 'metadata': {'index_fields': ['name']}, 'belongs_to_set': None, 'description': 'The process of obtaining information system resources that are relevant to an information need.'})\n",
"({'id': 'bc338a39-64d6-549a-acec-da60846dd90d', 'name': 'natural language processing', 'type': 'Entity', 'created_at': 1750270947426, 'updated_at': 1750270947426, 'ontology_valid': False, 'version': 1, 'topological_rank': 0, 'metadata': {'index_fields': ['name']}, 'belongs_to_set': None, 'description': 'An interdisciplinary subfield of computer science and information retrieval.'}, {'relationship_name': 'is_a_subfield_of', 'source_node_id': 'bc338a39-64d6-549a-acec-da60846dd90d', 'target_node_id': '6218dbab-eb6a-5759-a864-b3419755ffe0', 'ontology_valid': False}, {'id': '6218dbab-eb6a-5759-a864-b3419755ffe0', 'name': 'computer science', 'type': 'Entity', 'created_at': 1750270947427, 'updated_at': 1750270947427, 'ontology_valid': False, 'version': 1, 'topological_rank': 0, 'metadata': {'index_fields': ['name']}, 'belongs_to_set': None, 'description': 'The study of computation, data processing, and information systems.'})\n",
"({'id': 'bc338a39-64d6-549a-acec-da60846dd90d', 'name': 'natural language processing', 'type': 'Entity', 'created_at': 1750270947426, 'updated_at': 1750270947426, 'ontology_valid': False, 'version': 1, 'topological_rank': 0, 'metadata': {'index_fields': ['name']}, 'belongs_to_set': None, 'description': 'An interdisciplinary subfield of computer science and information retrieval.'}, {'relationship_name': 'is_a', 'source_node_id': 'bc338a39-64d6-549a-acec-da60846dd90d', 'target_node_id': 'dd9713b7-dc20-5101-aad0-1c4216811147', 'updated_at': '2025-06-18 18:22:32'}, {'id': 'dd9713b7-dc20-5101-aad0-1c4216811147', 'name': 'concept', 'type': 'EntityType', 'created_at': 1750270947426, 'updated_at': 1750270947426, 'ontology_valid': False, 'version': 1, 'topological_rank': 0, 'metadata': {'index_fields': ['name']}, 'belongs_to_set': None, 'description': 'concept'})\n",
"({'id': 'dd9713b7-dc20-5101-aad0-1c4216811147', 'name': 'concept', 'type': 'EntityType', 'created_at': 1750270947426, 'updated_at': 1750270947426, 'ontology_valid': False, 'version': 1, 'topological_rank': 0, 'metadata': {'index_fields': ['name']}, 'belongs_to_set': None, 'description': 'concept'}, {'relationship_name': 'is_a', 'source_node_id': 'bc338a39-64d6-549a-acec-da60846dd90d', 'target_node_id': 'dd9713b7-dc20-5101-aad0-1c4216811147', 'updated_at': '2025-06-18 18:22:32'}, {'id': 'bc338a39-64d6-549a-acec-da60846dd90d', 'name': 'natural language processing', 'type': 'Entity', 'created_at': 1750270947426, 'updated_at': 1750270947426, 'ontology_valid': False, 'version': 1, 'topological_rank': 0, 'metadata': {'index_fields': ['name']}, 'belongs_to_set': None, 'description': 'An interdisciplinary subfield of computer science and information retrieval.'})\n"
]
}
],
"source": [
"# Display results\n",
"for result_text in search_results:\n",
" print(result_text)"
]
},
{
"cell_type": "markdown",
"id": "129615f70ac937ef",
"metadata": {},
"source": [
"## Assigning scores to nodes in the graph\n",
"In this section, we show how to assign scores to nodes in the graph. We will use the page rank\n",
"algorithm for this purpose."
]
},
{
"cell_type": "markdown",
"id": "2d5cb30252b5993a",
"metadata": {},
"source": [
"First, we get the graph (knowledge_graph) from the cognee engine."
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "8d81b01a72d42529",
"metadata": {
"ExecuteTime": {
"end_time": "2025-04-22T20:28:17.193207Z",
"start_time": "2025-04-22T20:28:17.186961Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Graph engine loaded successfully.\n",
"\n",
"Graph object:\n",
"8 nodes\n",
"10 edges\n"
]
}
],
"source": [
"from cognee.infrastructure.databases.graph import get_graph_engine\n",
"graph_engine = await get_graph_engine()\n",
"(nodes, edges) = await graph_engine.get_graph_data()\n",
"print(\"Graph engine loaded successfully.\\n\")\n",
"print(\"Graph object:\")\n",
"print(len(nodes), 'nodes')\n",
"print(len(edges), 'edges')"
]
},
{
"cell_type": "markdown",
"id": "253c3e7a55a627ae",
"metadata": {},
"source": [
"Then, we inspect the nodes and its data in the graph."
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "5c48132d2d16b777",
"metadata": {
"ExecuteTime": {
"end_time": "2025-04-22T20:20:19.362858Z",
"start_time": "2025-04-22T20:20:19.356823Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"--- ('ec72faa8-a238-52f7-b159-81272937347e', {'name': '', 'type': 'DocumentChunk', 'created_at': 1750270944579, 'updated_at': 1750270944579, 'ontology_valid': False, 'version': 1, 'topological_rank': 0, 'metadata': {'index_fields': ['text']}, 'belongs_to_set': None, 'text': '\\nNatural language processing (NLP) is an interdisciplinary\\nsubfield of computer science and information retrieval.\\n', 'chunk_size': 36, 'chunk_index': 0, 'cut_type': 'paragraph_end'})\n",
"--- ('998dd02b-b033-502f-a273-5bfe7d3b3eb1', {'name': 'text_a796439b56064944e6c73f7751917e91', 'type': 'TextDocument', 'created_at': 1750270944572, 'updated_at': 1750270944572, 'ontology_valid': False, 'version': 1, 'topological_rank': 0, 'metadata': {'index_fields': ['name']}, 'belongs_to_set': None, 'raw_data_location': '/Users/borisarzentar/Projects/Topoteretes/cognee/cognee/.data_storage/data/text_a796439b56064944e6c73f7751917e91.txt', 'external_metadata': '{}', 'mime_type': 'text/plain'})\n",
"--- ('02bdab9a-0981-518c-a0d4-1684e0329447', {'name': 'information retrieval', 'type': 'Entity', 'created_at': 1750270947427, 'updated_at': 1750270947427, 'ontology_valid': False, 'version': 1, 'topological_rank': 0, 'metadata': {'index_fields': ['name']}, 'belongs_to_set': None, 'description': 'The process of obtaining information system resources that are relevant to an information need.'})\n",
"--- ('0198571b-3e94-50ea-8b9f-19e3a31080c0', {'name': 'field', 'type': 'EntityType', 'created_at': 1750270947426, 'updated_at': 1750270947426, 'ontology_valid': False, 'version': 1, 'topological_rank': 0, 'metadata': {'index_fields': ['name']}, 'belongs_to_set': None, 'description': 'field'})\n",
"--- ('6218dbab-eb6a-5759-a864-b3419755ffe0', {'name': 'computer science', 'type': 'Entity', 'created_at': 1750270947427, 'updated_at': 1750270947427, 'ontology_valid': False, 'version': 1, 'topological_rank': 0, 'metadata': {'index_fields': ['name']}, 'belongs_to_set': None, 'description': 'The study of computation, data processing, and information systems.'})\n",
"--- ('bc338a39-64d6-549a-acec-da60846dd90d', {'name': 'natural language processing', 'type': 'Entity', 'created_at': 1750270947426, 'updated_at': 1750270947426, 'ontology_valid': False, 'version': 1, 'topological_rank': 0, 'metadata': {'index_fields': ['name']}, 'belongs_to_set': None, 'description': 'An interdisciplinary subfield of computer science and information retrieval.'})\n",
"--- ('dd9713b7-dc20-5101-aad0-1c4216811147', {'name': 'concept', 'type': 'EntityType', 'created_at': 1750270947426, 'updated_at': 1750270947426, 'ontology_valid': False, 'version': 1, 'topological_rank': 0, 'metadata': {'index_fields': ['name']}, 'belongs_to_set': None, 'description': 'concept'})\n",
"--- ('3230db46-ad6d-5a66-af88-357d1dd2a2e3', {'name': '', 'type': 'TextSummary', 'created_at': 1750270952124, 'updated_at': 1750270952124, 'ontology_valid': False, 'version': 1, 'topological_rank': 0, 'metadata': {'index_fields': ['text']}, 'belongs_to_set': None, 'text': 'Natural language processing (NLP) is a multidisciplinary branch of computer science and information retrieval.'})\n"
]
}
],
"source": [
"# Print the first 10 nodes in the graph with their data\n",
"for node in nodes[:10]:\n",
" print('---',node)"
]
},
{
"cell_type": "markdown",
"id": "b6d25c6c77bab8d5",
"metadata": {},
"source": [
"The node data consists of a few fields:"
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "c99e319b3646b234",
"metadata": {
"ExecuteTime": {
"end_time": "2025-04-22T20:23:47.082650Z",
"start_time": "2025-04-22T20:23:47.077861Z"
}
},
"outputs": [
{
"data": {
"text/plain": [
"dict_keys(['name', 'type', 'created_at', 'updated_at', 'ontology_valid', 'version', 'topological_rank', 'metadata', 'belongs_to_set', 'text'])"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"node[1].keys()"
]
},
{
"cell_type": "markdown",
"id": "674f15fac7d14059",
"metadata": {},
"source": [
"We can see how the graph looks, using nx drawing tools."
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "a344f3b96685c122",
"metadata": {
"ExecuteTime": {
"end_time": "2025-04-22T20:30:45.374685Z",
"start_time": "2025-04-22T20:30:44.856090Z"
}
},
"outputs": [
{
"data": {
"image/png": "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",
"text/plain": [
"<Figure size 640x480 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"import matplotlib.pyplot as plt\n",
"\n",
"import networkx as nx\n",
"\n",
"graph = nx.MultiDiGraph()\n",
"graph.add_nodes_from(nodes)\n",
"graph.add_edges_from(edges)\n",
"\n",
"pos = nx.spring_layout(graph, seed=42) # positions for all nodes\n",
"nx.draw(graph, pos, with_labels=False, node_size=100, node_color='white',\n",
" edge_color='gray',\n",
" edgecolors='black', alpha=0.5)\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"id": "5201aeb75f7ddf00",
"metadata": {},
"source": [
"We can now add a new field: page rank score. We first compute them using the networkx library."
]
},
{
"cell_type": "code",
"execution_count": 12,
"id": "97734d83d57d62ef",
"metadata": {
"ExecuteTime": {
"end_time": "2025-04-22T20:26:03.564879Z",
"start_time": "2025-04-22T20:26:03.557142Z"
}
},
"outputs": [],
"source": [
"import networkx as nx\n",
"ranks = nx.pagerank(graph)"
]
},
{
"cell_type": "markdown",
"id": "33507b44e7910b57",
"metadata": {},
"source": [
"We can take a look at the ranks of the first 10 nodes."
]
},
{
"cell_type": "code",
"execution_count": 13,
"id": "70677c7fc481682a",
"metadata": {
"ExecuteTime": {
"end_time": "2025-04-22T20:27:14.819317Z",
"start_time": "2025-04-22T20:27:14.807163Z"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"ec72faa8-a238-52f7-b159-81272937347e /rank: 0.1263134587793514\n",
"998dd02b-b033-502f-a273-5bfe7d3b3eb1 /rank: 0.09511967865839628\n",
"02bdab9a-0981-518c-a0d4-1684e0329447 /rank: 0.12207032848939373\n",
"0198571b-3e94-50ea-8b9f-19e3a31080c0 /rank: 0.2757995171468045\n",
"6218dbab-eb6a-5759-a864-b3419755ffe0 /rank: 0.12207032848939373\n",
"bc338a39-64d6-549a-acec-da60846dd90d /rank: 0.09511967865839628\n",
"dd9713b7-dc20-5101-aad0-1c4216811147 /rank: 0.09522882980463071\n",
"3230db46-ad6d-5a66-af88-357d1dd2a2e3 /rank: 0.06827817997363327\n"
]
}
],
"source": [
"for node in list(ranks)[:10]:\n",
" print(node, '/rank:', ranks[node])"
]
},
{
"cell_type": "markdown",
"id": "50f6b51f62a65cc7",
"metadata": {},
"source": [
"Finally, we can get a feeling of the distribution of the ranks."
]
},
{
"cell_type": "code",
"execution_count": 14,
"id": "648db7aec21f8b3b",
"metadata": {
"ExecuteTime": {
"end_time": "2025-04-22T20:31:54.910597Z",
"start_time": "2025-04-22T20:31:54.285586Z"
}
},
"outputs": [
{
"data": {
"text/plain": [
"Text(0.5, 1.0, 'Page rank distribution')"
]
},
"execution_count": 14,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAzoAAAHDCAYAAADss29MAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjMsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvZiW1igAAAAlwSFlzAAAPYQAAD2EBqD+naQAAJ5pJREFUeJzt3QuQVeVhB/BvRVlQYRFRXiJgICCioCgKacQHgpSx0rEp0jSgRZK2ajWmtcGmEjQdaIivGCJSqySxBh+J0FGjIgIWgVoeNoKRiiGCykOisIIKyt7Od2buZhd2YS/ssrsfv9/MYfec+51zvnvvmcv97/c4RblcLhcAAAASckR9VwAAAKC2CToAAEByBB0AACA5gg4AAJAcQQcAAEiOoAMAACRH0AEAAJIj6AAAAMkRdAAAgOQIOgAcEt/97ndDUVFR2LJlS60fs6IuXbqEq666KtS13/3ud9m5Z8yYUb4tnvfYY48Nh0o8f3wNANiboANQC+KX3filM780a9YsfPGLXwzXXXdd2LRpU31Xj/145plnGmxgaMh1A2jIjqzvCgCk5Lbbbgtdu3YNn376aVi4cGG47777si+qK1euDEcffXR9V++wsHr16nDEEYX9HS++R1OnTi0oUHTu3Dl88skn4aijjjqAWtZO3eL5jzzSf+UAVfHpCFCLhg0bFs4+++zs92uuuSYcf/zx4c477wyzZ88Oo0aNCg1dWVlZ2LVrV9Yi1VgVFxfX6fE///zz7HVq2rRpvb9O9X1+gIZM1zWAOnTRRRdlP9euXZv9/MEPfhAGDhyYBaDmzZuHfv36hSeeeKLKv9T/3d/9XWjTpk1o0aJF+JM/+ZPw7rvvVjkmI27/q7/6q9C2bdvsS/5pp50WHnzwwRrVLx4vdq/7j//4j2y/uP+zzz5bUF3zx5g1a1bo3bt3eR3yx9mXt99+O3Tr1i3bb39d/GIL2TnnnJN9uf/CF74Q7r///irL7TlG57PPPgsTJ04M3bt3z/aNz+eP/uiPwpw5c7LHY9nYYpJ/Lvml4jic+Frcfffd2Xnj83v99derHKOT99vf/jYMHTo0HHPMMaFDhw5ZS18ulyt/fP78+dm+8WdFex5zX3XLb9vzelixYkUWuFu2bJmNF7r44ovDkiVLquxq+fLLL4ebbropnHDCCVld//RP/zS8//77+3wfABoLLToAdeitt97KfsYv19E999yThZavfvWrWcvJzJkzw1e+8pXw1FNPheHDh5fvF7/gPvbYY+FrX/taOO+888KCBQsqPZ4Xw0F8PB824hfWX/3qV2Hs2LGhtLQ03Hjjjfut44svvpidK+4fg1UMCoXUNR9CfvnLX4a//du/zYLZD3/4w3DFFVeEdevWlT/3ql6bGARbt26dhY547uq89tprYciQIdnzi1/sY6vKhAkTsnC3P7H8pEmTsha2/v37Z6/L0qVLw/Lly8Mll1wSvvGNb4T33nsvq8PPfvazKo/x0EMPZd0Rv/71r2dBJ9Y5tupUZffu3eHSSy/N3pfvf//7WeCLdY11joGnEDWpW0WrVq0KX/7yl7OQc/PNN2fd6mIgvOCCC7Jr6Nxzz61U/vrrrw/HHXdcVr8YsmKYi9fBo48+WlA9ARqkHAAH7aGHHop/rs+98MILuffffz+3fv363MyZM3PHH398rnnz5rl33nknK/fxxx9X2m/Xrl253r175y666KLybcuWLcuOdeONN1Yqe9VVV2XbJ0yYUL5t7Nixufbt2+e2bNlSqeyVV16ZKykp2et8e4rHO+KII3KrVq3a67Ga1DV/jKZNm+bWrFlTvu1///d/s+333ntv+bZY77gtvj6/+c1vch06dMidc845uQ8++CC3PyNGjMg1a9Ys9/bbb5dve/3113NNmjTJjllR586dc2PGjClf79OnT2748OH7PP61116713GitWvXZttbtmyZ27x5c5WPxfc+L543brv++uvLt5WVlWXnj69RfO7RvHnzsnLx5/6OWV3doj2vh/g6xfO89dZb5dvee++9XIsWLXLnn3/+Xtfr4MGDs/rlffOb38xe061bt+7z9QJoDHRdA6hFgwcPzlodOnXqFK688sqs69CTTz4ZOnbsmD0eu4Dlffjhh2Hbtm3ZX+Bj60JevstXbB3Z86/vFcXvub/4xS/CZZddlv0ep23OL7HbVDx2xeNWZ9CgQaFXr157ba9JXSs+79itK++MM87IWhViF649xYkZ4jljy9ELL7yQtSjsS2whee6558KIESPCySefXL791FNPzZ7n/rRq1Spr6XjzzTfDgYqtU/F9ranYKpKXb22LrWLx+daV+Do9//zz2et0yimnlG9v3759+Iu/+Ius1S22ZlUUW6gqdoWL7288TuxSCNDY6boGUIvieIo4rXSc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",
"text/plain": [
"<Figure size 1000x500 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"fig, ax = plt.subplots(figsize=(10, 5))\n",
"plt.hist(list(ranks.values()), bins=60)\n",
"plt.title('Page rank distribution')"
]
},
{
"cell_type": "markdown",
"id": "4e011e5c95dcfe5c",
"metadata": {},
"source": [
"As we can see, some nodes have a very high score, while most of them are around 0.01. Let's see\n",
"the data of the node with the highest score."
]
},
{
"cell_type": "code",
"execution_count": 15,
"id": "b2e83e84cd9bf6a5",
"metadata": {
"ExecuteTime": {
"end_time": "2025-04-22T20:33:06.355984Z",
"start_time": "2025-04-22T20:33:06.352761Z"
}
},
"outputs": [],
"source": [
"# Sort the ranks dictionary by value in descending order\n",
"sorted_ranks = sorted(ranks.items(), key=lambda x: x[1], reverse=True)"
]
},
{
"cell_type": "code",
"execution_count": 16,
"id": "a8a49371bc7640ca",
"metadata": {
"ExecuteTime": {
"end_time": "2025-04-22T20:33:16.681400Z",
"start_time": "2025-04-22T20:33:16.665675Z"
}
},
"outputs": [
{
"data": {
"text/plain": [
"('0198571b-3e94-50ea-8b9f-19e3a31080c0', 0.2757995171468045)"
]
},
"execution_count": 16,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"sorted_ranks[0]"
]
},
{
"cell_type": "code",
"execution_count": 17,
"id": "e9a594c0fe27dea",
"metadata": {
"ExecuteTime": {
"end_time": "2025-04-22T20:33:40.483516Z",
"start_time": "2025-04-22T20:33:40.479188Z"
}
},
"outputs": [
{
"data": {
"text/plain": [
"{'name': 'field',\n",
" 'type': 'EntityType',\n",
" 'created_at': 1750270947426,\n",
" 'updated_at': 1750270947426,\n",
" 'ontology_valid': False,\n",
" 'version': 1,\n",
" 'topological_rank': 0,\n",
" 'metadata': {'index_fields': ['name']},\n",
" 'belongs_to_set': None,\n",
" 'description': 'field'}"
]
},
"execution_count": 17,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"graph.nodes[sorted_ranks[0][0]] # get the node data"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "95227d160bddb696",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": ".venv",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.5"
}
},
"nbformat": 4,
"nbformat_minor": 5
}