Help us shape the future of Go! Take the 2026 Go Developer Survey

rag

package
v1.4.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 31, 2026 License: MIT Imports: 40 Imported by: 0

Documentation

Overview

Package rag implements retrieval-augmented generation: loading documents, splitting them into chunks, embedding and indexing the chunks, and retrieving them for agents through a search tool or a context provider.

The pipeline follows the component split of frameworks such as Eino (loader, parser, transformer, indexer, retriever):

  • A Loader reads documents from files (FSLoader) or URLs (URLLoader). A Parser turns bytes into documents: text, Markdown, HTML, JSON, JSON Lines and CSV are built in. PDF and other binary formats need an external parser; register one in FSLoader.Parsers or implement Loader.
  • A Splitter cuts documents into chunks: RecursiveSplitter, MarkdownSplitter, CodeSplitter and AutoSplitter, which picks one of the others per document. Sizes are measured in tokens by a pluggable LengthFunc that defaults to the estimate of the context package.
  • An Index embeds chunks in batches with a memory.Embedder and stores them in a VectorStore, such as MemoryStore. Sync re-indexes only sources whose content changed and deletes sources that disappeared. An optional Enricher, such as ContextualEnricher, adds a short LLM-written context to each chunk before it is embedded.
  • Retrievers rank chunks: Vector (cosine similarity), Keyword (BM25), Hybrid (reciprocal rank fusion) and Reranked, which reorders the candidates of another retriever with a Reranker such as LLMReranker.
  • Tool exposes an index to a model as a read-only search tool, and Provider retrieves relevant chunks automatically for each run.

Index

Constants

View Source
const (
	// MetaFormat is the document format: "text", "markdown", "html",
	// "json", "csv" or "code".
	MetaFormat = "format"
	// MetaLanguage is the programming language of a code document, such as
	// "go", "python", "javascript" or "typescript".
	MetaLanguage = "language"
	// MetaPath is the slash-separated path of a file relative to the root
	// of its FSLoader.
	MetaPath = "path"
	// MetaURL is the final URL of a document loaded by URLLoader.
	MetaURL = "url"
	// MetaContentType is the media type of a document loaded by URLLoader.
	MetaContentType = "content_type"
	// MetaTitle is the title of an HTML document.
	MetaTitle = "title"
	// MetaRecord is the 1-based number of a JSON Lines line, JSON array
	// element or CSV row.
	MetaRecord = "record"
	// MetaHeaders is the path of Markdown headers above a chunk, as a
	// []string from the outermost header.
	MetaHeaders = "headers"
)

Metadata keys set by the loaders, parsers and splitters of this package.

View Source
const (
	DefaultChunkSize    = 512
	DefaultChunkOverlap = 64
)

Default chunk sizes in tokens.

View Source
const DefaultBatchSize = 64

DefaultBatchSize is the default number of chunks embedded per request.

View Source
const DefaultContextInstruction = "" /* 203-byte string literal not displayed */

DefaultContextInstruction is the instruction of ContextualEnricher, from Anthropic's contextual retrieval prompt.

View Source
const DefaultMaxFileSize = 10 << 20

DefaultMaxFileSize is the default size limit of FSLoader and URLLoader.

View Source
const DefaultRerankPrompt = `` /* 306-byte string literal not displayed */

DefaultRerankPrompt is the system prompt of LLMReranker.

Variables

View Source
var DefaultSeparators = []string{"\n\n", "\n", ". ", "。", " ", ""}

DefaultSeparators are the separators of RecursiveSplitter: paragraphs, lines, sentences, words and finally characters.

Functions

func ChunkID

func ChunkID(source, documentID string, offset int) string

ChunkID returns the stable ID of the chunk of a document that starts at offset: a hash of the source, the document ID and the offset.

func DefaultParsers

func DefaultParsers() map[string]Parser

DefaultParsers returns the parsers FSLoader uses by file extension: text (.txt, .text, .rst, .log, .yaml, .yml, .toml, .xml, .ini, .cfg), Markdown (.md, .markdown, .mdx), HTML (.html, .htm, .xhtml), JSON as text (.json), JSON Lines with whole records (.jsonl, .ndjson), CSV (.csv) and TSV (.tsv), and Go, Python, JavaScript and TypeScript code.

func Format

func Format(hits []Hit, opts FormatOptions) string

Format renders hits for a prompt, numbered for citation, each with its source, section, chunk ID and score followed by its content.

func LanguageSeparators

func LanguageSeparators(lang string) []string

LanguageSeparators returns the regular expression separators that CodeSplitter uses for a language: "go", "python" or "javascript" (also "typescript"), or common aliases and extensions such as "py" and "ts". It returns nil for other languages.

func Provider

func Provider(r Retriever, k int) actx.Provider

Provider returns a context provider that retrieves up to k chunks relevant to each run's input from r, usually an Index, and adds them as a reminder, as the agent's memory provider does for memories. A non-positive k selects 3.

func Tool

func Tool(r Retriever, opts ToolOptions) tool.Tool

Tool returns a read-only tool that searches r, usually an Index, and returns the matching chunks numbered for citation with their sources, IDs and scores. The citations are also returned in the result metadata under "citations" as []Citation.

Types

type AutoSplitter

type AutoSplitter struct {
	// Size, Overlap and Length are as in RecursiveSplitter.
	Size, Overlap int
	Length        LengthFunc
}

AutoSplitter chooses a splitter for each document from its metadata: MarkdownSplitter with HeaderContext for MetaFormat "markdown", CodeSplitter for documents with a MetaLanguage and RecursiveSplitter otherwise.

func (*AutoSplitter) Split

func (s *AutoSplitter) Split(ctx context.Context, doc *Document) ([]*Chunk, error)

Split implements Splitter.

type CSVParser

type CSVParser struct {
	// Comma is the field delimiter. Defaults to ','.
	Comma rune
	// ContentColumns form the content. Defaults to every column.
	ContentColumns []string
	// MetadataColumns are copied to the document metadata as strings.
	MetadataColumns []string
	// IDColumn names a column that identifies rows.
	IDColumn string
}

CSVParser parses CSV with a header row into one document per row. The content is "column: value" lines of the content columns with non-empty values. Document IDs are the source followed by "#" and the IDColumn value, or the 1-based row number, which is also stored as MetaRecord.

func (CSVParser) Parse

func (p CSVParser) Parse(ctx context.Context, source string, data []byte) ([]*Document, error)

Parse implements Parser.

type Cache

type Cache interface {
	Get(key string) (string, bool)
	Put(key, value string)
}

Cache stores generated text by key. Implementations must be safe for concurrent use.

type ChangeLoader added in v1.4.0

type ChangeLoader interface {
	LoadChanges(ctx context.Context, cursor string) (*Changes, error)
}

ChangeLoader reads an authoritative delta since an opaque application-held cursor. Permission failures and incomplete listings fail the whole call; they must never be reported as deletions. An empty cursor starts a snapshot.

type Changes added in v1.4.0

type Changes struct {
	Documents      []*Document `json:"documents"`
	DeletedSources []string    `json:"deleted_sources"`
	Cursor         string      `json:"cursor"`
}

Changes is a complete delta from a ChangeLoader. Cursor is committed by the application only after every document and deletion has been applied. A delta is not a full snapshot and must not be passed to Index.Sync.

type Chunk

type Chunk struct {
	// ID is stable: it is derived from the source, the document ID and the
	// offset, so re-splitting unchanged content yields the same IDs.
	ID         string `json:"id"`
	DocumentID string `json:"document_id"`
	Source     string `json:"source,omitempty"`
	// Index is the position of the chunk within its document.
	Index int `json:"index"`
	// Offset is the byte offset of Content within the document content.
	Offset  int    `json:"offset"`
	Content string `json:"content"`
	// Context situates the chunk within its document, such as a Markdown
	// header path or text written by ContextualEnricher. It is prepended to
	// Content for embedding and keyword search; see Text.
	Context  string         `json:"context,omitempty"`
	Metadata map[string]any `json:"metadata,omitempty"`
	// Embedding is set by the Index. Stores share it between the copies
	// they return, so it must not be modified.
	Embedding []float32 `json:"embedding,omitempty"`
}

Chunk is a piece of a document, the unit that is embedded, stored and retrieved.

func (*Chunk) Text

func (c *Chunk) Text() string

Text returns the text that is embedded and searched: Context and Content separated by a blank line.

type Citation

type Citation struct {
	// N is the number of the hit in the output, starting at 1.
	N      int     `json:"n"`
	ID     string  `json:"id"`
	Source string  `json:"source"`
	Score  float64 `json:"score"`
}

Citation identifies a hit included in formatted output.

type CodeSplitter

type CodeSplitter struct {
	// Language selects the separators. When empty, the document's
	// MetaLanguage metadata is used; unknown languages use the separators
	// of RecursiveSplitter.
	Language string
	// Size, Overlap and Length are as in RecursiveSplitter.
	Size, Overlap int
	Length        LengthFunc
}

CodeSplitter splits source code at declaration boundaries before falling back to blank lines, lines and words. See LanguageSeparators.

func (*CodeSplitter) Split

func (s *CodeSplitter) Split(ctx context.Context, doc *Document) ([]*Chunk, error)

Split implements Splitter.

type Config

type Config struct {
	// Store stores the chunks. Defaults to a new MemoryStore.
	Store VectorStore
	// Writer optionally selects a non-atomic ingestion backend. Store must be
	// nil when Writer is supplied. Set Retriever to query that backend; without
	// it the index supports ingestion only and retrieval returns an error.
	Writer SourceWriter
	// Embedder embeds chunks. Without it chunks are stored without
	// embeddings and only keyword retrieval works.
	Embedder memory.Embedder
	// QueryEmbedder embeds queries. Defaults to Embedder. Use it with
	// embedders that distinguish queries from documents; both must produce
	// vectors in the same space.
	QueryEmbedder memory.Embedder
	// Splitter splits documents. Defaults to AutoSplitter{}.
	Splitter Splitter
	// Enricher, if set, runs on the chunks of each document before they
	// are embedded, such as a ContextualEnricher.
	Enricher Enricher
	// BatchSize is the number of chunks embedded per request. Defaults to
	// DefaultBatchSize.
	BatchSize int
	// Version is included in the content hash of every source. Change it
	// after changing the splitter, enricher or embedder so that the next
	// Add or Sync re-indexes sources whose content did not change.
	Version string
	// Retriever replaces the default retriever: Keyword, fused with Vector
	// by Hybrid when an embedder is set.
	Retriever Retriever
	// Reranker, if set, reranks the candidates of the retriever; see
	// Reranked.
	Reranker Reranker
	// Candidates is the number of hits to rerank; see Reranked.
	Candidates int
	// OnError receives retrieval errors that do not fail a query, such as
	// a failing retriever of Hybrid or a failing Reranker. If nil, they are
	// logged with slog.Default.
	OnError func(err error)
}

Config configures an Index.

type ContextualEnricher

type ContextualEnricher struct {
	Model model.Model
	// Instruction follows the chunk in the user message. Defaults to
	// DefaultContextInstruction.
	Instruction string
	// MaxDocumentBytes truncates long documents. Defaults to 100000, about
	// 25000 tokens of English text.
	MaxDocumentBytes int
	// MaxTokens bounds each context. Defaults to 200.
	MaxTokens int
	// Concurrency is the number of chunks enriched in parallel. Defaults to
	// 4.
	Concurrency int
	// Cache stores contexts. Defaults to a MapCache owned by the enricher;
	// supply a persistent cache to reuse contexts across processes.
	Cache Cache
	// contains filtered or unexported fields
}

ContextualEnricher implements contextual retrieval: a model writes a short context that situates each chunk within its document, and the context is prepended to the chunk for embedding and keyword search (see Chunk.Text), after any context the splitter set.

The document is sent as the system prompt and the chunk as the user message, so the requests for the chunks of one document share a prefix that providers with prompt caching can reuse. Contexts are cached by a hash of the instruction, the document and the chunk, so re-indexing unchanged content does not call the model again.

func (*ContextualEnricher) Enrich

func (e *ContextualEnricher) Enrich(ctx context.Context, doc *Document, chunks []*Chunk) error

Enrich implements Enricher. It fails when any context cannot be generated.

type Document

type Document struct {
	// ID identifies the document. It defaults to Source.
	ID      string `json:"id"`
	Content string `json:"content"`
	// Metadata is copied to every chunk of the document.
	Metadata map[string]any `json:"metadata,omitempty"`
	// Source names where the document came from, such as a file path or a
	// URL. Documents with the same source are indexed and replaced
	// together; a source defaults to the document ID.
	Source string `json:"source,omitempty"`
}

Document is a unit of loaded content, such as a file, a web page or a CSV row.

func LoadAll

func LoadAll(ctx context.Context, loaders ...Loader) ([]*Document, error)

LoadAll loads the documents of every loader in order.

type Enricher

type Enricher interface {
	Enrich(ctx context.Context, doc *Document, chunks []*Chunk) error
}

Enricher adds information to the chunks of a document before they are embedded, typically by setting Chunk.Context.

type EnricherFunc

type EnricherFunc func(ctx context.Context, doc *Document, chunks []*Chunk) error

EnricherFunc adapts a function to Enricher.

func (EnricherFunc) Enrich

func (f EnricherFunc) Enrich(ctx context.Context, doc *Document, chunks []*Chunk) error

Enrich calls f.

type FSLoader

type FSLoader struct {
	FS fs.FS
	// Root is the directory to load, relative to FS. Defaults to ".".
	Root string
	// Include, when non-empty, loads only files matching one of these
	// globs. Patterns without a slash match file names; others match paths
	// relative to Root. "**" matches any number of directories and "{a,b}"
	// alternatives.
	Include []string
	// Exclude skips files and directories matching one of these globs,
	// which work like Include.
	Exclude []string
	// GitIgnore skips paths excluded by .gitignore files within Root.
	// Ignore files above Root and git's global excludes do not apply.
	GitIgnore bool
	// Parsers maps lower-case file extensions, such as ".md", to parsers.
	// Defaults to DefaultParsers. Files without a parser are skipped.
	Parsers map[string]Parser
	// MaxFileSize skips larger files. Defaults to DefaultMaxFileSize.
	MaxFileSize int64
	// SourcePrefix is prepended to document sources, for example to tell
	// apart several directories in one index.
	SourcePrefix string
}

FSLoader loads the files of a file system, such as os.DirFS(dir), that have a parser for their extension. Directories named .git are skipped.

Document sources are SourcePrefix followed by the slash-separated path relative to Root, which is also stored as MetaPath.

func (*FSLoader) Load

func (l *FSLoader) Load(ctx context.Context) ([]*Document, error)

Load implements Loader.

type Filter

type Filter struct {
	// Sources matches chunks whose source is one of these when non-empty.
	Sources []string
	// SourcePrefix matches chunks whose source starts with it.
	SourcePrefix string
	// Metadata matches chunks whose metadata has every key with an equal
	// value. Numbers are compared by value whatever their type, and slices
	// element by element, so values decoded from JSON match the originals.
	Metadata map[string]any
}

Filter selects chunks. The zero value matches every chunk.

func (Filter) Match

func (f Filter) Match(c *Chunk) bool

Match reports whether c satisfies the filter.

type FormatOptions

type FormatOptions struct {
	// MaxChunkBytes bounds each hit's content, including its truncation note.
	// Defaults to 2000.
	MaxChunkBytes int
	// MaxBytes bounds the whole text: hits that would exceed it are
	// replaced by an omission note when space permits, except the first,
	// which is truncated instead. All notes count toward the byte limit.
	// Defaults to 10000.
	MaxBytes int
}

FormatOptions bounds the text rendered by Format.

type HTMLParser

type HTMLParser struct{}

HTMLParser converts HTML to plain text with the converter of the web_fetch tool and stores the page title as MetaTitle.

func (HTMLParser) Parse

func (HTMLParser) Parse(_ context.Context, source string, data []byte) ([]*Document, error)

Parse implements Parser.

type Hit

type Hit struct {
	Chunk *Chunk
	Score float64
}

Hit is a retrieved chunk with its relevance score. Scores are retriever specific.

type Hybrid

type Hybrid struct {
	Retrievers []Retriever
	// Weights scale the contribution of each retriever. Missing weights
	// are 1.
	Weights []float64
	// K is the RRF constant. Defaults to 60.
	K float64
	// OnError receives the error of each retriever that fails while
	// another succeeds.
	OnError func(err error)
}

Hybrid fuses several retrievers with reciprocal rank fusion: a chunk scores the sum of Weight/(K+rank) over the retrievers that return it.

A retriever that fails does not fail the query: Hybrid fuses the hits of the others and reports the failure to OnError, or logs it with slog.Default when OnError is nil. Retrieve returns an error only when every retriever fails.

func (*Hybrid) Retrieve

func (h *Hybrid) Retrieve(ctx context.Context, q Query) ([]Hit, error)

Retrieve implements Retriever. Each retriever is asked for three times the limit and Query.MinScore applies to each retriever's own scores, not to the fused score.

type Index

type Index struct {
	// contains filtered or unexported fields
}

Index embeds and stores the chunks of documents and retrieves them.

Documents are indexed by source: all documents with the same source are split, embedded and replaced together. Each source is stored with a hash of its documents and Config.Version, so Add and Sync skip sources whose content did not change. Adding, syncing and deleting are serialized; retrieval may run concurrently with them.

func NewIndex

func NewIndex(cfg Config) *Index

NewIndex returns an Index.

func (*Index) Add

func (ix *Index) Add(ctx context.Context, docs ...*Document) (*Result, error)

Add indexes documents, replacing the chunks of their sources. Sources whose content did not change are skipped. On error, completed sources are reported in the result. A non-atomic Writer may have partially changed the failing source; retry it before committing a loader's cursor.

func (*Index) ApplyChanges added in v1.4.0

func (ix *Index) ApplyChanges(ctx context.Context, changes *Changes) (*Result, error)

ApplyChanges applies additions before explicit deletions. On failure callers retain the old cursor and may retry the delta. It never infers deletions from documents missing from a partial listing.

func (*Index) Delete

func (ix *Index) Delete(ctx context.Context, sources ...string) error

Delete removes sources from the index.

func (*Index) Retrieve

func (ix *Index) Retrieve(ctx context.Context, q Query) ([]Hit, error)

Retrieve implements Retriever with the configured retriever.

func (*Index) Search

func (ix *Index) Search(ctx context.Context, query string, limit int) ([]Hit, error)

Search retrieves up to limit chunks relevant to query.

func (*Index) Store

func (ix *Index) Store() VectorStore

Store returns the atomic store, or nil for an external Writer.

func (*Index) Sync

func (ix *Index) Sync(ctx context.Context, docs []*Document, opts ...SyncOption) (*Result, error)

Sync makes the index match docs: it adds new sources, re-indexes sources whose content changed and deletes indexed sources that are not among docs. Unchanged sources are skipped. Deletions happen after all additions succeeded.

type JSONParser

type JSONParser struct {
	// Lines parses JSON Lines (NDJSON).
	Lines bool
	// ContentFields form the content. One field yields its value, several
	// yield "field: value" lines. Strings are used as-is and other values
	// as JSON. When empty, the content is the whole record as JSON.
	ContentFields []string
	// MetadataFields are copied to the document metadata under their
	// paths.
	MetadataFields []string
	// IDField names a field that identifies records.
	IDField string
}

JSONParser parses JSON records. A top-level array yields one record per element and any other value a single record; with Lines, each non-blank line is a record. Fields are named by dot-separated paths into objects, such as "author.name".

Document IDs are the source followed by "#" and the IDField value, or the 1-based record number, which is also stored as MetaRecord. Records without content are skipped.

func (JSONParser) Parse

func (p JSONParser) Parse(ctx context.Context, source string, data []byte) ([]*Document, error)

Parse implements Parser.

type Keyword

type Keyword struct {
	Store VectorStore
	// K1 and B are the BM25 parameters. Zero selects the defaults, 1.2 and
	// 0.75; a negative value selects 0.
	K1, B float64
	// contains filtered or unexported fields
}

Keyword ranks chunks with BM25 over Chunk.Text, tokenized like memory (words, and unigrams and bigrams of CJK characters).

When the store implements Revisioner, Keyword caches its inverted index until the store changes, and term statistics then come from all chunks rather than only those matching the filter. Otherwise it lists and indexes the matching chunks for every query. Neither Store nor the Keyword may be changed or copied after first use.

func (*Keyword) Retrieve

func (k *Keyword) Retrieve(ctx context.Context, q Query) ([]Hit, error)

Retrieve implements Retriever.

type LLMReranker

type LLMReranker struct {
	Model model.Model
	// Prompt is the system prompt. Defaults to DefaultRerankPrompt.
	Prompt string
	// MaxPassageBytes truncates each passage. Defaults to 2000.
	MaxPassageBytes int
	// MaxTokens bounds the reply. Defaults to 256.
	MaxTokens int
}

LLMReranker reranks hits by asking a model to order them by relevance. Hits the model leaves out are dropped. Scores become 1 for the first hit and decrease linearly with rank.

func (*LLMReranker) Rerank

func (r *LLMReranker) Rerank(ctx context.Context, query string, hits []Hit) ([]Hit, error)

Rerank implements Reranker.

type LengthFunc

type LengthFunc func(string) int

LengthFunc measures text, usually in tokens.

type Loader

type Loader interface {
	Load(ctx context.Context) ([]*Document, error)
}

Loader loads documents.

Load fails as a whole when any source cannot be read or parsed, rather than returning the documents it could load, so that Index.Sync never deletes a source because it was temporarily unreadable.

type LoaderFunc

type LoaderFunc func(ctx context.Context) ([]*Document, error)

LoaderFunc adapts a function to Loader.

func (LoaderFunc) Load

func (f LoaderFunc) Load(ctx context.Context) ([]*Document, error)

Load calls f.

type MapCache

type MapCache struct {
	// contains filtered or unexported fields
}

MapCache is an in-memory Cache. The zero value is ready to use.

func (*MapCache) Get

func (c *MapCache) Get(key string) (string, bool)

Get implements Cache.

func (*MapCache) Put

func (c *MapCache) Put(key, value string)

Put implements Cache.

type MarkdownSplitter

type MarkdownSplitter struct {
	// Size, Overlap and Length are as in RecursiveSplitter.
	Size, Overlap int
	Length        LengthFunc
	// MaxLevel is the deepest header level that starts a section. Defaults
	// to 6.
	MaxLevel int
	// HeaderContext sets Chunk.Context to the header path, joined with
	// " > ", so it is embedded and searched with each chunk.
	HeaderContext bool
}

MarkdownSplitter splits Markdown into sections at ATX headers ("#" to "######"), ignoring headers inside fenced code blocks, and splits each section that is too large with a RecursiveSplitter. Each chunk records the header path above it in MetaHeaders. Sections that hold nothing but their header are dropped, since their children carry the header path. Setext headers (underlined with "=" or "-") are not recognized.

func (*MarkdownSplitter) Split

func (s *MarkdownSplitter) Split(_ context.Context, doc *Document) ([]*Chunk, error)

Split implements Splitter.

type MemoryStore

type MemoryStore struct {
	// contains filtered or unexported fields
}

MemoryStore keeps chunks in process memory and searches them exhaustively. The zero value is ready to use.

func NewMemoryStore

func NewMemoryStore() *MemoryStore

NewMemoryStore returns an empty in-memory store.

func (*MemoryStore) Delete

func (s *MemoryStore) Delete(_ context.Context, sources ...string) error

Delete implements VectorStore.

func (*MemoryStore) List

func (s *MemoryStore) List(_ context.Context, f Filter) ([]*Chunk, error)

List implements VectorStore.

func (*MemoryStore) Replace

func (s *MemoryStore) Replace(_ context.Context, sources ...SourceChunks) error

Replace implements VectorStore.

func (*MemoryStore) Revision

func (s *MemoryStore) Revision() uint64

Revision implements Revisioner.

func (*MemoryStore) Search

func (s *MemoryStore) Search(_ context.Context, vector []float32, limit int, f Filter) ([]Hit, error)

Search implements VectorStore.

func (*MemoryStore) Sources

func (s *MemoryStore) Sources(context.Context) ([]SourceInfo, error)

Sources implements VectorStore.

type Parser

type Parser interface {
	Parse(ctx context.Context, source string, data []byte) ([]*Document, error)
}

Parser turns the bytes of a source into documents. Parsers set the document IDs and sources from source.

PDF, Office documents and other binary formats are not supported by the standard library; implement Parser with a library of your choice and register it in FSLoader.Parsers or set it as URLLoader.Parser.

type ParserFunc

type ParserFunc func(ctx context.Context, source string, data []byte) ([]*Document, error)

ParserFunc adapts a function to Parser.

func (ParserFunc) Parse

func (f ParserFunc) Parse(ctx context.Context, source string, data []byte) ([]*Document, error)

Parse calls f.

type Query

type Query struct {
	Text string
	// Limit is the maximum number of hits; non-positive means no limit.
	Limit  int
	Filter Filter
	// MinScore drops hits scoring below it. Scores are retriever specific.
	MinScore float64
}

Query is a retrieval request.

type RecursiveSplitter

type RecursiveSplitter struct {
	// Size is the maximum chunk length measured by Length. Defaults to
	// DefaultChunkSize. A single character longer than Size is kept whole.
	Size int
	// Overlap is the length shared by consecutive chunks. Zero selects
	// DefaultChunkOverlap (at most a quarter of Size); a negative value
	// disables overlap.
	Overlap int
	// Length measures text. Defaults to the token estimate of the context
	// package (four ASCII bytes or one other character per token).
	Length LengthFunc
	// Separators are tried in order. Defaults to DefaultSeparators.
	Separators []string
	// Regexp interprets the separators as regular expressions.
	Regexp bool
}

RecursiveSplitter splits text at the first separator that occurs in it, merges adjacent pieces into chunks of at most Size and splits pieces that are still too large with the next separators, as LangChain's RecursiveCharacterTextSplitter does. Consecutive chunks cut from the same run of pieces share up to Overlap of text.

Text is cut after a separator, so it stays with the preceding piece, except that a separator that starts with white space followed by other text, such as "\nfunc ", is cut after the white space so the rest begins the next piece. The empty separator splits between characters. Chunks are trimmed of surrounding white space and are exact substrings of the document, so Chunk.Offset locates them.

func (*RecursiveSplitter) Split

func (s *RecursiveSplitter) Split(_ context.Context, doc *Document) ([]*Chunk, error)

Split implements Splitter.

type Reranked

type Reranked struct {
	Retriever Retriever
	Reranker  Reranker
	// Candidates is the number of first-stage hits to rerank. Defaults to
	// four times the limit, and at least 20.
	Candidates int
	OnError    func(err error)
}

Reranked retrieves candidates with Retriever and reorders them with Reranker, the second stage of the retrieval pipeline recommended by Anthropic's contextual retrieval study.

When the reranker fails, Reranked keeps the first-stage order and reports the error to OnError, or logs it with slog.Default when OnError is nil. Query.MinScore applies to the first stage.

func (*Reranked) Retrieve

func (r *Reranked) Retrieve(ctx context.Context, q Query) ([]Hit, error)

Retrieve implements Retriever.

type Reranker

type Reranker interface {
	Rerank(ctx context.Context, query string, hits []Hit) ([]Hit, error)
}

Reranker reorders candidate hits by relevance to a query. It may drop hits it judges irrelevant.

type RerankerFunc

type RerankerFunc func(ctx context.Context, query string, hits []Hit) ([]Hit, error)

RerankerFunc adapts a function to Reranker.

func (RerankerFunc) Rerank

func (f RerankerFunc) Rerank(ctx context.Context, query string, hits []Hit) ([]Hit, error)

Rerank calls f.

type Result

type Result struct {
	// Added lists new sources, Updated sources whose content changed,
	// Unchanged sources that were skipped and Deleted removed sources.
	Added, Updated, Unchanged, Deleted []string
	// Chunks is the number of chunks stored.
	Chunks int
}

Result reports the sources changed by Add or Sync.

type Retriever

type Retriever interface {
	Retrieve(ctx context.Context, q Query) ([]Hit, error)
}

Retriever finds chunks relevant to a query.

type RetrieverFunc

type RetrieverFunc func(ctx context.Context, q Query) ([]Hit, error)

RetrieverFunc adapts a function to Retriever.

func (RetrieverFunc) Retrieve

func (f RetrieverFunc) Retrieve(ctx context.Context, q Query) ([]Hit, error)

Retrieve calls f.

type Revisioner

type Revisioner interface {
	Revision() uint64
}

Revisioner is implemented by stores that count their changes, such as MemoryStore. Keyword caches its index until the revision changes.

type SourceChunks

type SourceChunks struct {
	Info   SourceInfo `json:"info"`
	Chunks []*Chunk   `json:"chunks"`
}

SourceChunks is the indexed content of a source.

type SourceInfo

type SourceInfo struct {
	Source string `json:"source"`
	// Hash identifies the indexed content of the source; see Index.
	Hash      string    `json:"hash"`
	Chunks    int       `json:"chunks"`
	IndexedAt time.Time `json:"indexed_at"`
}

SourceInfo records an indexed source.

type SourceWriter added in v1.4.0

type SourceWriter interface {
	Write(ctx context.Context, sources ...SourceChunks) error
	Delete(ctx context.Context, sources ...string) error
	Sources(ctx context.Context) ([]SourceInfo, error)
}

SourceWriter persists an index by source, without promising atomic replacement. A failed Write or Delete may have changed the failing source. Implementations invalidate its recorded hash before changing chunks, so Add/Sync can retry incomplete work. Successful writes record the supplied source hash. Reads may observe an incomplete replacement. Applications serialize independent writers to the same namespace. VectorStore retains its stronger atomic contract.

type Splitter

type Splitter interface {
	Split(ctx context.Context, doc *Document) ([]*Chunk, error)
}

Splitter cuts documents into chunks.

type SyncOption

type SyncOption func(*syncConfig)

SyncOption configures Sync.

func SyncPrefix

func SyncPrefix(prefix string) SyncOption

SyncPrefix restricts the deletions of Sync to sources starting with prefix, so an index can hold sources from several loaders, for example an FSLoader with a SourcePrefix.

type TextParser

type TextParser struct {
	// Format is stored as MetaFormat. Defaults to "text".
	Format string
	// Language is stored as MetaLanguage when non-empty.
	Language string
}

TextParser parses text into a single document. It drops a UTF-8 byte order mark, converts CRLF line endings to LF and replaces invalid UTF-8. Content with NUL bytes is treated as binary and yields no document.

func (TextParser) Parse

func (p TextParser) Parse(_ context.Context, source string, data []byte) ([]*Document, error)

Parse implements Parser.

type ToolOptions

type ToolOptions struct {
	// Name defaults to "search_knowledge".
	Name string
	// Description defaults to a generic description of a knowledge base
	// search. Describe what the knowledge base holds so the model knows
	// when to search it.
	Description string
	// Limit is the default number of results. Defaults to 5.
	Limit int
	// MaxLimit caps the number of results the model may request. Defaults
	// to 20.
	MaxLimit int
	// Filter restricts every search.
	Filter Filter
	// Format bounds the output.
	Format FormatOptions
}

ToolOptions configures Tool.

type URLLoader

type URLLoader struct {
	URLs []string
	// Client sends the requests. Defaults to a client with a 60 second
	// timeout.
	Client *http.Client
	// Header is added to every request.
	Header http.Header
	// Parser, when set, parses every response.
	Parser Parser
	// MaxBytes fails on larger responses. Defaults to DefaultMaxFileSize.
	MaxBytes int64
}

URLLoader loads documents over HTTP. The parser is chosen by media type: HTML, Markdown, JSON, JSON Lines and CSV; for other text types, no type or application/octet-stream, by the extension of the final URL path as in DefaultParsers, falling back to plain text for text types. Other media types are an error unless Parser is set.

Document sources are the URLs as given; the final URL after redirects is stored as MetaURL and the media type as MetaContentType. The URLs are chosen by the application, so unlike the web_fetch tool, URLLoader does not refuse private network addresses; set Client to restrict them.

func (*URLLoader) Load

func (l *URLLoader) Load(ctx context.Context) ([]*Document, error)

Load implements Loader.

type Vector

type Vector struct {
	Store VectorStore
	// Embedder embeds the query. It must produce vectors in the same space
	// as the embedder of the index.
	Embedder memory.Embedder
}

Vector ranks chunks by the cosine similarity of their embeddings to the query's, as computed by the store. Hits with a non-positive similarity are dropped.

func (*Vector) Retrieve

func (v *Vector) Retrieve(ctx context.Context, q Query) ([]Hit, error)

Retrieve implements Retriever.

type VectorStore

type VectorStore interface {
	// Replace replaces all chunks of each source, recording its info. Each
	// source is replaced atomically.
	Replace(ctx context.Context, sources ...SourceChunks) error
	// Delete removes sources and their chunks. Unknown sources are
	// ignored.
	Delete(ctx context.Context, sources ...string) error
	// Sources returns the indexed sources ordered by name.
	Sources(ctx context.Context) ([]SourceInfo, error)
	// List returns the chunks matching f, ordered by source, document and
	// position.
	List(ctx context.Context, f Filter) ([]*Chunk, error)
	// Search returns up to limit chunks matching f with an embedding,
	// ranked by cosine similarity to vector. A non-positive limit returns
	// all of them.
	Search(ctx context.Context, vector []float32, limit int, f Filter) ([]Hit, error)
}

VectorStore stores chunks and their embeddings, grouped by source.

Implementations must be safe for concurrent use. Chunks passed in and returned are copies, except that embeddings and values within metadata may be shared and must be treated as immutable.

Directories

Path Synopsis
Package ragtest checks rag.VectorStore implementations against the contract the built-in store follows.
Package ragtest checks rag.VectorStore implementations against the contract the built-in store follows.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL