Commit graph

23 commits

Author SHA1 Message Date
Daniel Chalef
1a6db24600 Final MMR optimization focused on 1024D vectors with smart dimensionality dispatch
This commit delivers a production-ready MMR optimization specifically tailored for
Graphiti's primary use case while handling high-dimensional vectors appropriately.

## Performance Improvements for 1024D Vectors
- **Average 1.16x speedup** (13.6% reduction in search latency)
- **Best performance: 1.31x speedup** for 25 candidates (23.5% faster)
- **Sub-millisecond latency**: 0.266ms for 10 candidates, 0.662ms for 25 candidates
- **Scalable performance**: Maintains improvements up to 100 candidates

## Smart Algorithm Dispatch
- **1024D vectors**: Uses optimized precomputed similarity matrix approach
- **High-dimensional vectors (≥2048D)**: Falls back to original algorithm to avoid overhead
- **Adaptive thresholds**: Considers both dataset size and dimensionality for optimal performance

## Key Optimizations for Primary Use Case
1. **Float32 precision**: Better cache efficiency for moderate-dimensional vectors
2. **Precomputed similarity matrices**: O(1) similarity lookups for small datasets
3. **Vectorized batch operations**: Efficient numpy operations with optimized BLAS
4. **Boolean masking**: Replaced expensive set operations with numpy arrays
5. **Smart memory management**: Optimal layouts for CPU cache utilization

## Technical Implementation
- **Memory efficient**: All test cases fit in CPU cache (max 0.43MB for 100×1024D)
- **Cache-conscious**: Contiguous float32 arrays improve memory bandwidth
- **BLAS optimized**: Matrix multiplication leverages hardware acceleration
- **Correctness maintained**: All existing tests pass with identical results

## Production Impact
- **Real-time search**: Sub-millisecond performance for typical scenarios
- **Scalable**: Performance improvements across all tested dataset sizes
- **Robust**: Handles edge cases and high-dimensional vectors gracefully
- **Backward compatible**: Drop-in replacement with identical API

This optimization transforms MMR from a potential bottleneck into a highly efficient
operation for Graphiti's search pipeline, providing significant performance gains for
the most common use case (1024D vectors) while maintaining robustness for all scenarios.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-18 12:28:50 -07:00
Daniel Chalef
166c67492a Optimize MMR calculation with vectorized numpy operations
This commit implements a comprehensive optimization of the Maximal Marginal Relevance (MMR)
calculation in the search utilities. The key improvements include:

## Algorithm Improvements
- **True MMR Implementation**: Replaced the previous diversity-aware scoring with proper
  iterative MMR algorithm that greedily selects documents one at a time
- **Vectorized Operations**: Leveraged numpy's optimized BLAS operations through matrix
  multiplication instead of individual dot products
- **Adaptive Strategy**: Uses different optimization strategies for small (≤100) and large
  datasets to balance performance and memory usage

## Performance Optimizations
- **Memory Efficiency**: Reduced memory complexity from O(n²) to O(n) for large datasets
- **BLAS Optimization**: Proper use of matrix multiplication leverages optimized BLAS libraries
- **Batch Normalization**: Added `normalize_embeddings_batch()` for efficient L2 normalization
  of multiple embeddings at once
- **Early Termination**: Stops selection when no candidates meet minimum score threshold

## Key Changes
- `maximal_marginal_relevance()`: Complete rewrite with proper iterative MMR algorithm
- `normalize_embeddings_batch()`: New function for efficient batch normalization
- `_mmr_small_dataset()`: Optimized implementation for small datasets using precomputed
  similarity matrices
- Added comprehensive test suite with 9 test cases covering edge cases, correctness,
  and performance scenarios

## Benefits
- **Correctness**: Now implements true MMR algorithm instead of approximate diversity scoring
- **Memory Usage**: O(n) memory complexity vs O(n²) for the original implementation
- **Scalability**: Better performance characteristics for large datasets
- **Maintainability**: Cleaner, more readable code with comprehensive test coverage

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-18 11:54:15 -07:00
Preston Rasmussen
9422b6f5fb
Node dedupe efficiency (#490)
* update resolve extracted edge

* updated edge resolution

* dedupe nodes update

* single pass node resolution

* updates

* mypy updates

* Update graphiti_core/prompts/dedupe_nodes.py

Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com>

* remove unused imports

* mypy

---------

Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com>
2025-05-15 13:56:33 -04:00
Preston Rasmussen
fd9969b5a1
Update dedupe prompt (#457)
* improve dedupe logic

* cut summary length

* update unit tests
2025-05-07 23:23:31 -04:00
Preston Rasmussen
1193b25fa3
add_episode() refactor (#421)
* temporal updates

* update resolve nodes

* dedupe edge updates

* edge dedupe

* extract attributes

* update dynamic pydantic model

* first pass of extract node attributes

* no errors

* bug fixes

* bug fixes

* prompt updates

* prompt updates

* updates

* updates

* remove unused imports

* update tests based on changes

* remove unused import
2025-04-30 12:08:52 -04:00
Daniel Chalef
0f6ac57dab
chore: update version to 0.9.3 and restructure dependencies (#338)
* Bump version from 0.9.0 to 0.9.1 in pyproject.toml and update google-genai dependency to >=0.1.0

* Bump version from 0.9.1 to 0.9.2 in pyproject.toml

* Update google-genai dependency version to >=0.8.0 in pyproject.toml

* loc file

* Update pyproject.toml to version 0.9.3, restructure dependencies, and modify author format. Remove outdated Google API key note from README.md.

* upgrade poetry and ruff
2025-04-08 20:47:38 -07:00
Preston Rasmussen
9efa6762d7
entity typo (#274) 2025-02-24 12:44:17 -05:00
Preston Rasmussen
088029a80c
node label filters (#265)
* node label filters

* update

* add search filters

* updates

* bump versions

* update tests

* test update
2025-02-21 12:38:01 -05:00
Daniel Chalef
445dccc021
refactor: use utc_now() for consistent UTC datetime handling (#234)
* ensure utc timezones

* fix: dep cycle

---------

Co-authored-by: paulpaliychuk <pavlo.paliychuk.ca@gmail.com>
2024-12-09 10:36:04 -08:00
Preston Rasmussen
3199e893ed
add_fact endpoint (#207)
* add_fact endpoint

* bump version

* add edge invalidation

* update
2024-11-06 09:12:21 -05:00
Preston Rasmussen
e15c872900
Fix edge invalidation (#174)
* update edge operations

* add new tests
2024-10-07 11:45:31 -04:00
Preston Rasmussen
d7c20c1f59
Search refactor + Community search (#111)
* WIP

* WIP

* WIP

* community search

* WIP

* WIP

* integration tested

* tests

* tests

* mypy

* mypy

* format
2024-09-16 14:03:05 -04:00
Preston Rasmussen
42fb590606
Add group ids (#89)
* set and retrieve group ids

* update add episode with group id support

* add episode and search functional

* update bulk

* mypy updates

* remove unused imports

* update unit tests

* unit tests

* add optional uuid field

* format

* mypy

* ellipsis
2024-09-06 12:33:42 -04:00
Preston Rasmussen
06d8d9359f
Add Missing Node and edge CRUD (#51)
* add CRUD operations and fix search limit bugs

* format

* update tests

* å

* update tests to double limit call

* add default field

* format

* import correct field
2024-08-27 16:18:01 -04:00
Daniel Chalef
2d0705fc1b
Add get_nodes_by_query method to Graphiti class (#49)
* Add get_nodes_by_query method to Graphiti class

Add a method to the Graphiti class that wraps `get_relevant_nodes` and returns a list of nodes given a query.

* Add `get_nodes_by_query` method to the `Graphiti` class in `graphiti_core/graphiti.py`.
* Import `generate_embedding` from `graphiti_core/llm_client/utils.py`.
* Use `generate_embedding` to generate an embedding for the query.
* Call `get_relevant_nodes` with the generated embedding and return the relevant nodes.

Add an embedding function to `llm_client/utils.py`.

* Add `generate_embedding` function to `graphiti_core/llm_client/utils.py`.
* Accept an embedder and model_id as parameters.
* Generate an embedding for the given text and return it.

---

For more details, open the [Copilot Workspace session](https://copilot-workspace.githubnext.com/getzep/graphiti?shareId=XXXX-XXXX-XXXX-XXXX).

* address comments left by @danielchalef on #49 (Add get_nodes_by_query method to Graphiti class);

* fix ellipsis name in cla config

* feat: Add get_nodes_by_query method to Graphiti class

* chore: Cleanup unused files, add hybrid node search, add tests

---------

Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com>
Co-authored-by: paulpaliychuk <pavlo.paliychuk.ca@gmail.com>
2024-08-26 20:00:28 -07:00
Pavlo Paliychuk
6e8c964aef
chore: Add comments to graphiti methods (#40)
* chore: Add comments to graphiti methods

* chore: Update int test name + add header to test files

* chore: Add comments to episode type
2024-08-26 13:11:50 -04:00
Pavlo Paliychuk
0ed7739bc0
Controlled example (#37)
* chore: Add romeo runner

* fix: Linter

* dedupe fixes

* wip

* wip dump

* allbirds

* chore: Update romeo parser

* chore: Anthropic model fix

* allbirds runner

* format

* wip

* mypy updates

* update

* remove r

* update tests

* format

* wip

* wip

* wip

* chore: Strategically update the message

* chore: Add romeo runner

* fix: Linter

* wip

* wip dump

* chore: Update romeo parser

* chore: Anthropic model fix

* wip

* allbirds

* allbirds runner

* format

* wip

* wip

* mypy updates

* update

* remove r

* update tests

* format

* wip

* chore: Strategically update the message

* rebase and fix import issues

* Update package imports for graphiti_core in examples and utils

* nits

* chore: Update OpenAI GPT-4o model to gpt-4o-2024-08-06

* implement groq

* improvments & linting

* cleanup and nits

* Refactor package imports for graphiti_core in examples and utils

* Refactor package imports for graphiti_core in examples and utils

* chore: Nuke unused examples

* chore: Nuke unused examples

* chore: Only run type check on graphiti_core

* fix unit tests

* reformat

* unit test

* fix: Unit tests

* test: Add coverage for extract_date_strings_from_edge

* lint

* remove commented code

---------

Co-authored-by: prestonrasmussen <prasmuss15@gmail.com>
Co-authored-by: Daniel Chalef <131175+danielchalef@users.noreply.github.com>
2024-08-26 10:30:22 -04:00
Daniel Chalef
c5e52153c4
chore: Fix packaging (#38)
* feat: Update project name and description

The project name and description in the `pyproject.toml` file have been updated to reflect the changes made to the project.

* chore: Update pyproject.toml to include core package

The `pyproject.toml` file has been updated to include the `core` package in the list of packages. This change ensures that the `core` package is included when building the project.

* fix imports

* fix importats
2024-08-25 10:07:50 -07:00
Pavlo Paliychuk
605219f8c7
feat: Add real world dates extraction (#26)
* feat: Add real world dates extraction

* fix: Linter

* fix: 💄 mypy errors

* chore: handle invalid dates returned by the llm

* chore: Polish prompt

* reformat

* style: 💄 reformat
2024-08-23 14:18:45 -04:00
Pavlo Paliychuk
8a55f48f5e
Fix temporal invalidation unit tests (#23)
* wip

* wip

* wip

* fix: Linter errors

* fix formatting

* chore: fix ruff

* fix: Duplication

* chore: Fix unit tests for temporal invalidation

* attempt to fix unit tests

* fix: format

---------

Co-authored-by: Daniel Chalef <131175+danielchalef@users.noreply.github.com>
2024-08-22 19:02:20 -04:00
Daniel Chalef
73ec0146ff
ruff action (#17)
* ruff action

* chore: Update Python version to 3.10 in lint.yml workflow

* fix lint and formatting

* cleanup
2024-08-22 13:06:42 -07:00
Daniel Chalef
50da9d0f31
format and linting (#18)
* Makefile and format

* fix podcast stuff

* refactor: update import statement for transcript_parser in podcast_runner.py

* format and linting

* chore: Update import statements and remove unused code in maintenance module
2024-08-22 12:26:13 -07:00
Pavlo Paliychuk
a6fd0ddb75
feat: Initial version of temporal invalidation + tests (#8)
* feat: Initial version of temporal invalidation + tests

* fix: dont run int tests on CI

* fix: dont run int tests on CI

* fix: dont run int tests on CI

* fix: time of day issue

* fix: running non int tests in ci

* fix: running non int tests in ci

* fix: running non int tests in ci

* fix: running non int tests in ci

* fix: running non int tests in ci

* fix: running non int tests in ci

* fix: running non int tests in ci

* revert: Tests structural changes

* chore: Remove idea file

* chore: Get rid of NodesWithEdges class and define a triplet type instead
2024-08-20 16:29:19 -04:00