Quick Start
This page builds your first Heta KnowledgeBase from a local text file.
The first run builds the smallest vector knowledge base:
This path uses the fewest components. It is the fastest way to confirm that installation, model calls, parsing, chunking, and vector search are working. After that, add full-text search, Heta graph search, or benchmarks as needed.
Install
Heta is published on PyPI. Install it with the package name heta-framework; import it in Python with heta_framework.
The minimal vector example only needs the core package:
Install extras only when you need production stores or full-text indexing:
python -m pip install "heta-framework[sql]" # SQLStore and SQLite/PostgreSQL-style flows
python -m pip install "heta-framework[postgres]" # PostgreSQL driver
python -m pip install "heta-framework[mysql]" # MySQL driver
python -m pip install "heta-framework[milvus]" # Milvus VectorStore
python -m pip install "heta-framework[s3]" # S3-compatible ObjectStore
python -m pip install "heta-framework[text-index]" # Elasticsearch full-text index
Set your model API key:
Heta's model layer is powered by LiteLLM. model_name follows LiteLLM naming, for example openai/gpt-4o-mini or openai/text-embedding-3-small.
Build Your First KnowledgeBase
Create quickstart.py:
import asyncio
import os
import shutil
from pathlib import Path
from heta_framework.common.models import EmbeddingModel, LanguageModel
from heta_framework.common.stores import InMemoryVectorStore, LocalObjectStore
from heta_framework.kb import (
DocumentParserRegistry,
EmbedChunks,
IndexVectors,
KnowledgeBase,
KnowledgeModels,
KnowledgeParsers,
KnowledgeRecipe,
KnowledgeStores,
ParseDocuments,
SplitDocuments,
SplitDocumentsConfig,
TextParser,
)
async def main() -> None:
# 0. 准备一个干净 workspace;真实服务里通常换成你的业务目录或对象存储。
workspace = Path("heta-demo-vector")
shutil.rmtree(workspace, ignore_errors=True)
# 1. Stores:ObjectStore 管原始文件和中间产物,VectorStore 管向量索引。
objects = LocalObjectStore(workspace / "objects")
vectors = InMemoryVectorStore()
# 2. Models:Heta 的 model client 通过 LiteLLM 调用常见外部模型。
# 运行前设置:export OPENAI_API_KEY=...
language = LanguageModel(
model_name=os.getenv("HETA_LLM_MODEL", "openai/gpt-4o-mini"),
api_key=os.environ["OPENAI_API_KEY"],
)
embedding = EmbeddingModel(
model_name=os.getenv("HETA_EMBEDDING_MODEL", "openai/text-embedding-3-small"),
api_key=os.environ["OPENAI_API_KEY"],
)
# 3. 输入文档:这里写入一个 txt;PDF/HTML/Office 可以换成对应 parser。
await objects.put(
"raw/heta.txt",
(
"Heta builds KnowledgeBase objects from Recipe definitions. "
"Vector search retrieves chunks by semantic similarity."
).encode("utf-8"),
)
# 4. Recipe:声明 parser、model、store,以及要执行的 build steps。
recipe = KnowledgeRecipe(
parsers=KnowledgeParsers(documents=DocumentParserRegistry([TextParser()])),
models=KnowledgeModels(language=language, embedding=embedding),
stores=KnowledgeStores(objects=objects, vector=vectors),
steps=(
ParseDocuments(),
SplitDocuments(SplitDocumentsConfig(encoding_name="unicode")),
EmbedChunks(),
IndexVectors(),
),
)
# 5. Build + query:用真实 embedding API 建向量索引。
# generate_answer=True 时,query engine 会再调用 LLM 生成 answer。
kb = await KnowledgeBase.create(recipe=recipe, name="home-vector")
_raise_if_build_failed(kb)
response = await kb.query(
"How does Heta build a knowledge base?",
mode="vector_search",
top_k=1,
options={"generate_answer": True},
)
print(response.answer)
print(response.results[0].text)
await language.aclose()
await embedding.aclose()
await vectors.aclose()
await objects.aclose()
def _raise_if_build_failed(kb: KnowledgeBase) -> None:
if kb.run_record.status == "succeeded":
return
failed_step = next(
(record for record in reversed(kb.run_record.step_records) if record.status == "failed"),
None,
)
if failed_step is None:
raise RuntimeError(f"knowledge base build failed: {kb.run_record.status}")
raise RuntimeError(f"{failed_step.step_name} failed: {failed_step.error}")
asyncio.run(main())
Run it:
You should see output similar to:
Heta builds a knowledge base by creating KnowledgeBase objects from Recipe definitions [1].
Heta builds KnowledgeBase objects from Recipe definitions. Vector search retrieves chunks by semantic similarity.
The first line is the answer generated from retrieved evidence. The second line is the source chunk that was retrieved.
This example does three things:
- Writes
raw/heta.txtinto aLocalObjectStore. - Uses
TextParser,SplitDocuments, andEmbedChunksto create chunks and embeddings. - Uses
IndexVectorsto build a vector index and queries it withvector_search.
What The Recipe Does
The recipe is Heta's main build unit:
KnowledgeRecipe
parsers -> TextParser
models -> LanguageModel + EmbeddingModel
stores -> LocalObjectStore + InMemoryVectorStore
steps -> ParseDocuments -> SplitDocuments -> EmbedChunks -> IndexVectors
KnowledgeBase.create() executes this recipe. After the build, the KnowledgeBase only exposes the query modes that the recipe actually created.
In this minimal example:
If you add more steps, new query modes become available.
Generated Files
The example creates a local workspace:
heta-demo-vector/
objects/
raw/
heta.txt
parsed/
...
chunks/
...
embeddings/
...
_heta/
knowledge_bases/
home-vector/
manifest.json
latest_run.json
runs/
...
Where:
raw/stores input files.parsed/stores normalizedParsedDocumentfiles.chunks/storesParsedChunkfiles.embeddings/stores chunk embedding artifacts._heta/knowledge_bases/...stores KB runtime metadata forload(), recovery, anddelete().
This quickstart uses InMemoryVectorStore, so the vector index only lives in the current process. In production, replace it with MilvusVectorStore.
Add More Capabilities
Heta is designed for gradual composition. You do not need to choose the full architecture up front.
| You want | Add | You get |
|---|---|---|
| Semantic retrieval | EmbedChunks + IndexVectors |
vector_search |
| BM25-style keyword retrieval | IndexFullText + TextIndexStore |
full_text_search |
| SQL text persistence | PersistChunks + SQLStore |
sql_text_search |
| Heta-style graph retrieval | HetaGraphProcedure + SQL/vector stores |
heta_graph_search |
| Hybrid / rerank / rewrite / multi-hop | Vector, full-text, and graph assets | Heta query modes |
| Recipe evaluation | BenchmarkRunner + benchmark adapter |
EvaluationReport |
Recommended next steps:
- To understand Recipe, read What Is A Recipe.
- To choose a build path, read Choose A Build Path.
- To query a KB, read Query A KnowledgeBase.
- To evaluate build strategies, read Evaluate A Recipe.
Add Heta Graph Search
To try Heta-style graph building, add HetaGraphProcedure after the minimal vector KB path.
This path extracts entities and relations from chunks, writes graph facts into SQL and vector stores, and then opens heta_graph_search.
It requires SQL support:
Create graph_quickstart.py:
import asyncio
import os
import shutil
from pathlib import Path
from heta_framework.common.models import EmbeddingModel, LanguageModel
from heta_framework.common.stores import InMemoryVectorStore, LocalObjectStore, SQLStore
from heta_framework.kb import (
DocumentParserRegistry,
HetaGraphProcedure,
KnowledgeBase,
KnowledgeModels,
KnowledgeParsers,
KnowledgeRecipe,
KnowledgeStores,
ParseDocuments,
SplitDocuments,
SplitDocumentsConfig,
TextParser,
)
async def main() -> None:
# 0. 准备一个干净 workspace。
workspace = Path("heta-demo-graph")
shutil.rmtree(workspace, ignore_errors=True)
# 1. Stores:ObjectStore 管文件产物,SQLStore 落图谱 facts,VectorStore 支持图谱召回。
objects = LocalObjectStore(workspace / "objects")
sql = SQLStore(f"sqlite:///{workspace / 'graph.db'}")
vectors = InMemoryVectorStore()
# 2. Models:LLM 抽取 entity/relation,embedding model 为图谱 facts 建向量索引。
# 运行前设置:export OPENAI_API_KEY=...
language = LanguageModel(
model_name=os.getenv("HETA_LLM_MODEL", "openai/gpt-4o-mini"),
api_key=os.environ["OPENAI_API_KEY"],
)
embedding = EmbeddingModel(
model_name=os.getenv("HETA_EMBEDDING_MODEL", "openai/text-embedding-3-small"),
api_key=os.environ["OPENAI_API_KEY"],
)
# 3. 输入文档:Heta graph procedure 会从 chunk 中抽取 entity/relation。
await objects.put(
"raw/heta.txt",
(
"Heta builds knowledge bases from recipes. "
"A KnowledgeBase is created by running Recipe steps."
).encode("utf-8"),
)
# 4. Recipe:HetaGraphProcedure 会展开为 extract entities、extract relations、build graph。
recipe = KnowledgeRecipe(
parsers=KnowledgeParsers(documents=DocumentParserRegistry([TextParser()])),
models=KnowledgeModels(language=language, embedding=embedding),
stores=KnowledgeStores(objects=objects, sql=sql, vector=vectors),
steps=(
ParseDocuments(),
SplitDocuments(SplitDocumentsConfig(encoding_name="unicode")),
*HetaGraphProcedure.build(deduplicate=False).steps(),
),
)
# 5. Build + query:BuildGraph 会解锁 heta_graph_search。
kb = await KnowledgeBase.create(recipe=recipe, name="home-graph")
_raise_if_build_failed(kb)
response = await kb.query(
"How does Heta create a KnowledgeBase?",
mode="heta_graph_search",
top_k=3,
options={"generate_answer": True},
)
print(response.answer)
print(response.results[0].kind, response.results[0].text)
await language.aclose()
await embedding.aclose()
await sql.aclose()
await vectors.aclose()
await objects.aclose()
def _raise_if_build_failed(kb: KnowledgeBase) -> None:
if kb.run_record.status == "succeeded":
return
failed_step = next(
(record for record in reversed(kb.run_record.step_records) if record.status == "failed"),
None,
)
if failed_step is None:
raise RuntimeError(f"knowledge base build failed: {kb.run_record.status}")
raise RuntimeError(f"{failed_step.step_name} failed: {failed_step.error}")
asyncio.run(main())
Run it:
You should see output similar to:
Heta creates a KnowledgeBase by building it from recipes. Specifically, the process involves running the steps outlined in the recipes to construct the KnowledgeBase [1][2][3].
relation Relation: Heta -> KnowledgeBase
Name: builds
Type: creates
Description: Heta builds knowledge bases from recipes.
This example uses:
LocalObjectStorefor raw text and intermediate artifacts.SQLStorefor entities, relations, and evidence.InMemoryVectorStorefor graph fact vectors.HetaGraphProcedure.build(deduplicate=False)to expand Heta-style graph steps.
In production, replace SQLite with PostgreSQL and the in-memory vector store with Milvus. The recipe structure does not need to change.
Replace Local Components
Recipes are not tied to a storage implementation. Production deployment usually replaces components, not steps:
object_store = S3ObjectStore(...)
vector_store = MilvusVectorStore(...)
sql_store = SQLStore("postgresql+psycopg://postgres:postgres@host:5432/postgres")
The same recipe still builds with: