mirror of
https://github.com/perstarkse/minne.git
synced 2026-05-31 03:40:38 +02:00
chore: refactor retrieval pipeline to chunk-first RRF with derived entities and slimmer eval surface.
Collapse the multi-strategy entity engine into one benchmarked chunk retrieval path, derive entities from retrieved chunks, and update consumers, docs, and clippy fixes across the workspace.
This commit is contained in:
@@ -183,10 +183,8 @@ impl PipelineServices for DefaultPipelineServices {
|
||||
None => None,
|
||||
};
|
||||
|
||||
let config = retrieval_pipeline::RetrievalConfig::for_search(
|
||||
retrieval_pipeline::SearchTarget::EntitiesOnly,
|
||||
);
|
||||
match retrieval_pipeline::retrieve_entities(
|
||||
let config = retrieval_pipeline::RetrievalConfig::with_entities();
|
||||
match retrieval_pipeline::retrieve(
|
||||
&self.db,
|
||||
&self.openai_client,
|
||||
Some(&*self.embedding_provider),
|
||||
@@ -197,19 +195,16 @@ impl PipelineServices for DefaultPipelineServices {
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(retrieval_pipeline::StrategyOutput::Entities(entities)) => Ok(entities),
|
||||
Ok(retrieval_pipeline::StrategyOutput::Search(search)) => {
|
||||
let chunk_count = search.chunks.len();
|
||||
let entities = search.entities;
|
||||
Ok(retrieval_pipeline::RetrievalOutput::WithEntities { chunks, entities }) => {
|
||||
tracing::debug!(
|
||||
chunk_count,
|
||||
chunk_count = chunks.len(),
|
||||
entity_count = entities.len(),
|
||||
"ingestion search results returned entities"
|
||||
"ingestion retrieval resolved entities from chunks"
|
||||
);
|
||||
Ok(entities)
|
||||
}
|
||||
Ok(retrieval_pipeline::StrategyOutput::Chunks(_)) => Err(AppError::InternalError(
|
||||
"Ingestion retrieval should return entities".into(),
|
||||
Ok(retrieval_pipeline::RetrievalOutput::Chunks(_)) => Err(AppError::InternalError(
|
||||
"Ingestion retrieval should resolve entities".into(),
|
||||
)),
|
||||
Err(e) => Err(e),
|
||||
}
|
||||
@@ -372,16 +367,16 @@ mod tests {
|
||||
|
||||
fn system_prompt_from_request(
|
||||
request: &async_openai::types::CreateChatCompletionRequest,
|
||||
) -> String {
|
||||
let ChatCompletionRequestMessage::System(system) = &request.messages[0] else {
|
||||
panic!("expected first message to be system");
|
||||
) -> anyhow::Result<String> {
|
||||
let Some(ChatCompletionRequestMessage::System(system)) = request.messages.first() else {
|
||||
anyhow::bail!("expected first message to be system");
|
||||
};
|
||||
match &system.content {
|
||||
async_openai::types::ChatCompletionRequestSystemMessageContent::Text(text) => {
|
||||
text.clone()
|
||||
}
|
||||
other => panic!("unexpected system message content: {other:?}"),
|
||||
}
|
||||
let async_openai::types::ChatCompletionRequestSystemMessageContent::Text(text) =
|
||||
&system.content
|
||||
else {
|
||||
anyhow::bail!("unexpected system message content: {:?}", system.content);
|
||||
};
|
||||
Ok(text.clone())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
@@ -425,7 +420,7 @@ mod tests {
|
||||
.await
|
||||
.context("prepare llm request")?;
|
||||
|
||||
assert_eq!(system_prompt_from_request(&request), SENTINEL);
|
||||
assert_eq!(system_prompt_from_request(&request)?, SENTINEL);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,10 +125,10 @@ async fn render_pdf_pages(file_path: &Path, pages: &[u32]) -> Result<Vec<Vec<u8>
|
||||
})
|
||||
.await??;
|
||||
|
||||
for (idx, png) in captures.iter().enumerate() {
|
||||
if let Err(err) = maybe_dump_debug_image(page_numbers[idx], png).await {
|
||||
for (page_number, png) in page_numbers.iter().zip(captures.iter()) {
|
||||
if let Err(err) = maybe_dump_debug_image(*page_number, png).await {
|
||||
warn!(
|
||||
page = page_numbers[idx],
|
||||
page = page_number,
|
||||
error = %err,
|
||||
"Failed to write debug screenshot to disk"
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user