Skip to content

Commit d92db83

Browse files
authored
Merge pull request #16 from hallelx2/feat/answer-span-and-answer-api
feat: answer-span extraction + POST /v1/answer endpoint (Phase 1.1 + 3.3)
2 parents 1100390 + 39e677f commit d92db83

7 files changed

Lines changed: 998 additions & 25 deletions

File tree

cmd/engine/main.go

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -124,13 +124,17 @@ func run() error {
124124
q.Register(queue.KindIngestDocument, pipeline.Handler())
125125

126126
deps := api.Deps{
127-
Logger: logger,
128-
DB: pool,
129-
Storage: store,
130-
Queue: q,
131-
Strategy: strategy,
132-
Version: version,
133-
MultiDoc: multiDoc,
127+
Logger: logger,
128+
DB: pool,
129+
Storage: store,
130+
Queue: q,
131+
Strategy: strategy,
132+
Version: version,
133+
MultiDoc: multiDoc,
134+
LLM: llmClient,
135+
LLMModel: modelFor(cfg.LLM),
136+
AnswerSpan: cfg.Retrieval.AnswerSpan,
137+
Answer: cfg.Retrieval.Answer,
134138
}
135139

136140
srv := &http.Server{
@@ -228,6 +232,21 @@ func buildQueue(c config.QueueConfig, dbURL string) (queue.Queue, error) {
228232
}
229233
}
230234

235+
// modelFor returns the configured chat/general-purpose model name for
236+
// the selected LLM driver. Used as a fallback when an API request
237+
// omits an explicit model.
238+
func modelFor(c config.LLMConfig) string {
239+
switch c.Driver {
240+
case "anthropic":
241+
return c.Anthropic.Model
242+
case "openai":
243+
return c.OpenAI.Model
244+
case "gemini":
245+
return c.Gemini.Model
246+
}
247+
return ""
248+
}
249+
231250
func buildLLM(c config.LLMConfig) (llmgate.Client, error) {
232251
switch c.Driver {
233252
case "anthropic":

config.example.yaml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,28 @@ retrieval:
107107
# doesn't own, so the model knows what else exists in the document.
108108
include_sibling_breadcrumbs: true
109109

110+
# answer_span: when enabled, every section returned by /v1/query gets an
111+
# extra `answer_span` field carrying the verbatim quote the model judged
112+
# most relevant to the query, plus byte offsets back into the section's
113+
# content. Costs one LLM call per returned section. Opt-in by default.
114+
answer_span:
115+
enabled: false
116+
# Override the model used for span extraction; empty inherits the
117+
# request's model. Keep this on a cheap/fast model — the call is
118+
# short and runs once per returned section.
119+
model: ""
120+
max_concurrency: 4
121+
max_quote_len: 400
122+
123+
# answer: /v1/answer endpoint configuration. The endpoint runs
124+
# retrieval + per-section span extraction + a synthesis LLM call,
125+
# returning {answer, citations:[{section_id, page_start, page_end, quote}]}.
126+
answer:
127+
# Override the synthesis-call model; empty inherits the request's model.
128+
model: ""
129+
max_sections: 5
130+
max_answer_tokens: 1024
131+
110132
ingest:
111133
# The summarize and HyDE stages run concurrently. This caps the total
112134
# number of LLM calls in flight across both stages combined, so the

0 commit comments

Comments
 (0)