Repository navigation
Integrations
Noema plugs into LangChain and LlamaIndex as a retriever, and provides token counters that match specific model families.
Each integration imports its framework only when you create the class, so import noema never
requires either framework.
pip install "noema-rag[langchain]"from noema.integrations.langchain import NoemaRetriever
retriever = NoemaRetriever(kb=kb, top_k=5, hops=1, max_tokens=200, format="notation")
docs = retriever.invoke("Who is Google's CEO?")| Field | Default | Meaning |
|---|---|---|
kb |
required | A KnowledgeBase
|
top_k |
5 |
Vector search hits used as seeds |
hops |
1 |
Graph expansion distance |
max_tokens |
200 |
Token budget for the context |
format |
"notation" |
"notation" or "natural_language"
|
NoemaRetriever is a LangChain BaseRetriever, so it drops into chains and agents that expect
a retriever.
Each call returns at most one Document. Retrieval already assembles one token-budgeted
sub-graph, not independent chunks. page_content is the context text, and metadata holds:
| Key | Value |
|---|---|
entity_ids, relation_ids
|
Sorted lists of ids in the context |
token_count |
Tokens used |
truncated |
Whether the budget cut facts |
fact_matches |
List of {"relation_id", "score"}
|
source |
"noema" |
When nothing is found the retriever returns an empty list.
pip install "noema-rag[llamaindex]"from noema.integrations.llamaindex import NoemaLlamaIndexRetriever
retriever = NoemaLlamaIndexRetriever(kb, top_k=5, hops=1, max_tokens=200)
nodes = retriever.retrieve("Who is Google's CEO?")The arguments match the LangChain retriever, and kb is the first positional argument. The
assembled sub-graph comes back as one TextNode wrapped in a NodeWithScore. The score is the
best fact similarity from the vector search, or 1.0 if there were no scored matches but text was
still assembled. Metadata holds the same keys as above, except fact_matches.
Noema's own counts use the cl100k_base tiktoken encoding. For counts that match a model:
from noema.integrations.tokens import count_tokens_openai, count_tokens_anthropic
count_tokens_openai(text, model="gpt-4o")
count_tokens_anthropic(text, model="claude-sonnet-5", api_key=None)-
count_tokens_openai()uses tiktoken locally, and falls back tocl100k_basefor a model name tiktoken does not recognize. -
count_tokens_anthropic()calls Anthropic's token counting API. It needs theanthropicextra and an API key, passed asapi_keyor read fromANTHROPIC_API_KEY. If the package is missing or the call fails, it returns acl100k_baseestimate and emits aUserWarning, so a warning means the number is an estimate and not an exact Claude count. - Both return
0for empty or whitespace-only text.
No integration is required. retrieve() returns plain text:
context = kb.retrieve(question, max_tokens=200)
prompt = f"Use these facts:\n{context.text}\n\nQuestion: {question}"