mirror of
https://github.com/semantica-agi/semantica.git
synced 2026-09-06 04:00:19 +00:00
Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
de2cb70fda | ||
|
|
c5224aaa75 |
+27
-14
@@ -132,16 +132,17 @@ stats = context.store(
|
|||||||
print("Graph built: {} nodes, {} edges".format(
|
print("Graph built: {} nodes, {} edges".format(
|
||||||
stats["graph_nodes"], stats["graph_edges"]
|
stats["graph_nodes"], stats["graph_edges"]
|
||||||
))
|
))
|
||||||
# Graph built: 18 nodes, 14 edges
|
|
||||||
# Nodes: APT29, HAMMERTOSS, NATO, LifeCare, AS59796, CISA Sector 6, ...
|
|
||||||
# Edges: deployed, observed_on, classified_as, targets, operates_in, ...
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
`store()` returns a dict with `stored_count`, `memory_ids`, `graph_nodes`, and
|
||||||
|
`graph_edges`. The extracted nodes (APT29, HAMMERTOSS, LifeCare, AS59796, …) and
|
||||||
|
edges (`deployed`, `observed_on`, `classified_as`, …) now span all four documents.
|
||||||
|
|
||||||
The graph now contains a connected subgraph linking APT29 to healthcare infrastructure across four document boundaries, something that would be invisible to a pure vector search.
|
The graph now contains a connected subgraph linking APT29 to healthcare infrastructure across four document boundaries, something that would be invisible to a pure vector search.
|
||||||
|
|
||||||
## Retrieving the relevant subgraph
|
## Retrieving the relevant subgraph
|
||||||
|
|
||||||
With the graph populated, a plain `retrieve()` call already does more than vector search. When `use_graph=True`, the retriever seeds the graph traversal from the top-k vector matches and expands outward by following edges, collecting connected facts within `max_hops`:
|
With the graph populated, a plain `retrieve()` call already does more than vector search. When `use_graph=True`, the retriever seeds the graph traversal from the top-k vector matches and expands outward by following edges. Expansion depth is set once, by `max_expansion_hops` on the `AgentContext` constructor:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
results = context.retrieve(
|
results = context.retrieve(
|
||||||
@@ -149,7 +150,6 @@ results = context.retrieve(
|
|||||||
use_graph=True,
|
use_graph=True,
|
||||||
max_results=10,
|
max_results=10,
|
||||||
expand_graph=True,
|
expand_graph=True,
|
||||||
max_hops=3,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
for r in results:
|
for r in results:
|
||||||
@@ -175,11 +175,19 @@ apt29_intel = context.retrieve(
|
|||||||
use_graph=True,
|
use_graph=True,
|
||||||
anchor_node="APT29",
|
anchor_node="APT29",
|
||||||
proximity_weight=0.7, # strongly favour nodes close to APT29
|
proximity_weight=0.7, # strongly favour nodes close to APT29
|
||||||
max_hops=3,
|
max_hops=3, # with an anchor, this bounds the proximity radius
|
||||||
max_results=8,
|
max_results=8,
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
<Note>
|
||||||
|
`max_hops` on `retrieve()` only takes effect when `anchor_node` is set: it
|
||||||
|
bounds the proximity radius used for scoring and drops results farther than
|
||||||
|
`max_hops` from the anchor. Without an `anchor_node` it is ignored. It does
|
||||||
|
**not** change how far graph expansion reaches: that is fixed by
|
||||||
|
`max_expansion_hops` on the constructor.
|
||||||
|
</Note>
|
||||||
|
|
||||||
## Getting a grounded LLM answer with a reasoning path
|
## Getting a grounded LLM answer with a reasoning path
|
||||||
|
|
||||||
`retrieve()` gives you the grounded context. `query_with_reasoning()` goes one step further: it passes that subgraph context to an LLM and returns the answer together with the multi-hop path the retrieval system traced through the graph. That path is your audit trail.
|
`retrieve()` gives you the grounded context. `query_with_reasoning()` goes one step further: it passes that subgraph context to an LLM and returns the answer together with the multi-hop path the retrieval system traced through the graph. That path is your audit trail.
|
||||||
@@ -466,12 +474,17 @@ compliance_context = AgentContext(
|
|||||||
retention_days=2555, # 7-year regulatory retention
|
retention_days=2555, # 7-year regulatory retention
|
||||||
)
|
)
|
||||||
|
|
||||||
# In production these come from ingest_file(); shown as strings here for brevity
|
# In production the text comes from a parsed file, e.g. FileIngestor().ingest_file(path).text;
|
||||||
basel_cre20_text = "CRE20.32: For income-producing real estate where repayment depends on "
|
# inline strings here for brevity
|
||||||
"property cash flows, RWA = exposure × risk weight, where risk weight "
|
basel_cre20_text = (
|
||||||
"is determined by LTV bucket per Table CRE20.3..."
|
"CRE20.32: For income-producing real estate where repayment depends on "
|
||||||
bcbs239_text = "Principle 3: Risk data should be accurate and have a single authoritative source. "
|
"property cash flows, RWA = exposure × risk weight, where risk weight "
|
||||||
"Where data is aggregated across systems, reconciliation must be documented..."
|
"is determined by LTV bucket per Table CRE20.3..."
|
||||||
|
)
|
||||||
|
bcbs239_text = (
|
||||||
|
"Principle 3: Risk data should be accurate and have a single authoritative source. "
|
||||||
|
"Where data is aggregated across systems, reconciliation must be documented..."
|
||||||
|
)
|
||||||
|
|
||||||
compliance_context.store(
|
compliance_context.store(
|
||||||
[
|
[
|
||||||
@@ -535,7 +548,7 @@ results = context.retrieve(
|
|||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
Each additional hop in `max_hops` exponentially increases the subgraph size. Practical defaults by domain:
|
Each additional expansion hop exponentially increases the subgraph size. Practical defaults by domain:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
General Q&A max_expansion_hops=2 (95% of useful facts within 2 hops)
|
General Q&A max_expansion_hops=2 (95% of useful facts within 2 hops)
|
||||||
@@ -544,7 +557,7 @@ Drug interactions max_expansion_hops=3 (drug → enzyme → metabolite
|
|||||||
Regulatory cross-ref max_expansion_hops=2 (rule → article → article)
|
Regulatory cross-ref max_expansion_hops=2 (rule → article → article)
|
||||||
```
|
```
|
||||||
|
|
||||||
Set globally in the constructor; override per call with the `max_hops` argument to `retrieve()`.
|
Expansion depth is a constructor setting only (`max_expansion_hops`); there is no per-call override on `retrieve()`. `query_with_reasoning()` does take a per-call `max_hops` argument.
|
||||||
|
|
||||||
## How GraphRAG works internally
|
## How GraphRAG works internally
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user