Daniel.y commited on
Commit
13c7d05
·
unverified ·
2 Parent(s): 0a7a39d f70ff5d

Merge pull request #1538 from danielaskdd/ignore-chat-history-in-vector-search

Browse files
Files changed (1) hide show
  1. lightrag/operate.py +82 -97
lightrag/operate.py CHANGED
@@ -1198,71 +1198,9 @@ async def mix_kg_vector_query(
1198
  traceback.print_exc()
1199
  return None
1200
 
1201
- async def get_vector_context():
1202
- # Consider conversation history in vector search
1203
- augmented_query = query
1204
- if history_context:
1205
- augmented_query = f"{history_context}\n{query}"
1206
-
1207
- try:
1208
- # Reduce top_k for vector search in hybrid mode since we have structured information from KG
1209
- mix_topk = min(10, query_param.top_k)
1210
- results = await chunks_vdb.query(
1211
- augmented_query, top_k=mix_topk, ids=query_param.ids
1212
- )
1213
- if not results:
1214
- return None
1215
-
1216
- valid_chunks = []
1217
- for result in results:
1218
- if "content" in result:
1219
- # Directly use content from chunks_vdb.query result
1220
- chunk_with_time = {
1221
- "content": result["content"],
1222
- "created_at": result.get("created_at", None),
1223
- "file_path": result.get("file_path", None),
1224
- }
1225
- valid_chunks.append(chunk_with_time)
1226
-
1227
- if not valid_chunks:
1228
- return None
1229
-
1230
- maybe_trun_chunks = truncate_list_by_token_size(
1231
- valid_chunks,
1232
- key=lambda x: x["content"],
1233
- max_token_size=query_param.max_token_for_text_unit,
1234
- tokenizer=tokenizer,
1235
- )
1236
-
1237
- logger.debug(
1238
- f"Truncate chunks from {len(valid_chunks)} to {len(maybe_trun_chunks)} (max tokens:{query_param.max_token_for_text_unit})"
1239
- )
1240
- logger.info(
1241
- f"Naive query: {len(maybe_trun_chunks)} chunks, top_k: {mix_topk}"
1242
- )
1243
-
1244
- if not maybe_trun_chunks:
1245
- return None
1246
-
1247
- # Include time information in content
1248
- formatted_chunks = []
1249
- for c in maybe_trun_chunks:
1250
- chunk_text = "File path: " + c["file_path"] + "\r\n\r\n" + c["content"]
1251
- if c["created_at"]:
1252
- chunk_text = f"[Created at: {time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(c['created_at']))}]\r\n\r\n{chunk_text}"
1253
- formatted_chunks.append(chunk_text)
1254
-
1255
- logger.debug(
1256
- f"Truncate chunks from {len(valid_chunks)} to {len(formatted_chunks)} (max tokens:{query_param.max_token_for_text_unit})"
1257
- )
1258
- return "\r\n\r\n--New Chunk--\r\n\r\n".join(formatted_chunks)
1259
- except Exception as e:
1260
- logger.error(f"Error in get_vector_context: {e}")
1261
- return None
1262
-
1263
  # 3. Execute both retrievals in parallel
1264
  kg_context, vector_context = await asyncio.gather(
1265
- get_kg_context(), get_vector_context()
1266
  )
1267
 
1268
  # 4. Merge contexts
@@ -2043,44 +1981,12 @@ async def naive_query(
2043
  if cached_response is not None:
2044
  return cached_response
2045
 
2046
- results = await chunks_vdb.query(
2047
- query, top_k=query_param.top_k, ids=query_param.ids
2048
- )
2049
- if not len(results):
2050
- return PROMPTS["fail_response"]
2051
-
2052
- valid_chunks = [result for result in results if "content" in result]
2053
-
2054
- if not valid_chunks:
2055
- logger.warning("No valid chunks found after filtering")
2056
- return PROMPTS["fail_response"]
2057
-
2058
  tokenizer: Tokenizer = global_config["tokenizer"]
2059
- maybe_trun_chunks = truncate_list_by_token_size(
2060
- valid_chunks,
2061
- key=lambda x: x["content"],
2062
- max_token_size=query_param.max_token_for_text_unit,
2063
- tokenizer=tokenizer,
2064
- )
2065
 
2066
- if not maybe_trun_chunks:
2067
- logger.warning("No chunks left after truncation")
2068
  return PROMPTS["fail_response"]
2069
 
2070
- logger.debug(
2071
- f"Truncate chunks from {len(valid_chunks)} to {len(maybe_trun_chunks)} (max tokens:{query_param.max_token_for_text_unit})"
2072
- )
2073
- logger.info(
2074
- f"Naive query: {len(maybe_trun_chunks)} chunks, top_k: {query_param.top_k}"
2075
- )
2076
-
2077
- section = "\r\n\r\n--New Chunk--\r\n\r\n".join(
2078
- [
2079
- "File path: " + c["file_path"] + "\r\n\r\n" + c["content"]
2080
- for c in maybe_trun_chunks
2081
- ]
2082
- )
2083
-
2084
  if query_param.only_need_context:
2085
  return section
2086
 
@@ -2292,6 +2198,85 @@ async def kg_query_with_keywords(
2292
  return response
2293
 
2294
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2295
  async def query_with_keywords(
2296
  query: str,
2297
  prompt: str,
 
1198
  traceback.print_exc()
1199
  return None
1200
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1201
  # 3. Execute both retrievals in parallel
1202
  kg_context, vector_context = await asyncio.gather(
1203
+ get_kg_context(), _get_vector_context(query, chunks_vdb, query_param, tokenizer)
1204
  )
1205
 
1206
  # 4. Merge contexts
 
1981
  if cached_response is not None:
1982
  return cached_response
1983
 
 
 
 
 
 
 
 
 
 
 
 
 
1984
  tokenizer: Tokenizer = global_config["tokenizer"]
1985
+ section = await _get_vector_context(query, chunks_vdb, query_param, tokenizer)
 
 
 
 
 
1986
 
1987
+ if section is None:
 
1988
  return PROMPTS["fail_response"]
1989
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1990
  if query_param.only_need_context:
1991
  return section
1992
 
 
2198
  return response
2199
 
2200
 
2201
+ async def _get_vector_context(
2202
+ query: str,
2203
+ chunks_vdb: BaseVectorStorage,
2204
+ query_param: QueryParam,
2205
+ tokenizer: Tokenizer,
2206
+ ) -> str | None:
2207
+ """
2208
+ Retrieve vector context from the vector database.
2209
+
2210
+ This function performs vector search to find relevant text chunks for a query,
2211
+ formats them with file path and creation time information, and truncates
2212
+ the results to fit within token limits.
2213
+
2214
+ Args:
2215
+ query: The query string to search for
2216
+ chunks_vdb: Vector database containing document chunks
2217
+ query_param: Query parameters including top_k and ids
2218
+ tokenizer: Tokenizer for counting tokens
2219
+
2220
+ Returns:
2221
+ Formatted string containing relevant text chunks, or None if no results found
2222
+ """
2223
+ try:
2224
+ # Reduce top_k for vector search in hybrid mode since we have structured information from KG
2225
+ mix_topk = (
2226
+ min(10, query_param.top_k)
2227
+ if hasattr(query_param, "mode") and query_param.mode == "mix"
2228
+ else query_param.top_k
2229
+ )
2230
+ results = await chunks_vdb.query(query, top_k=mix_topk, ids=query_param.ids)
2231
+ if not results:
2232
+ return None
2233
+
2234
+ valid_chunks = []
2235
+ for result in results:
2236
+ if "content" in result:
2237
+ # Directly use content from chunks_vdb.query result
2238
+ chunk_with_time = {
2239
+ "content": result["content"],
2240
+ "created_at": result.get("created_at", None),
2241
+ "file_path": result.get("file_path", None),
2242
+ }
2243
+ valid_chunks.append(chunk_with_time)
2244
+
2245
+ if not valid_chunks:
2246
+ return None
2247
+
2248
+ maybe_trun_chunks = truncate_list_by_token_size(
2249
+ valid_chunks,
2250
+ key=lambda x: x["content"],
2251
+ max_token_size=query_param.max_token_for_text_unit,
2252
+ tokenizer=tokenizer,
2253
+ )
2254
+
2255
+ logger.debug(
2256
+ f"Truncate chunks from {len(valid_chunks)} to {len(maybe_trun_chunks)} (max tokens:{query_param.max_token_for_text_unit})"
2257
+ )
2258
+ logger.info(f"Vector query: {len(maybe_trun_chunks)} chunks, top_k: {mix_topk}")
2259
+
2260
+ if not maybe_trun_chunks:
2261
+ return None
2262
+
2263
+ # Include time information in content
2264
+ formatted_chunks = []
2265
+ for c in maybe_trun_chunks:
2266
+ chunk_text = "File path: " + c["file_path"] + "\r\n\r\n" + c["content"]
2267
+ if c["created_at"]:
2268
+ chunk_text = f"[Created at: {time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(c['created_at']))}]\r\n\r\n{chunk_text}"
2269
+ formatted_chunks.append(chunk_text)
2270
+
2271
+ logger.debug(
2272
+ f"Truncate chunks from {len(valid_chunks)} to {len(formatted_chunks)} (max tokens:{query_param.max_token_for_text_unit})"
2273
+ )
2274
+ return "\r\n\r\n--New Chunk--\r\n\r\n".join(formatted_chunks)
2275
+ except Exception as e:
2276
+ logger.error(f"Error in _get_vector_context: {e}")
2277
+ return None
2278
+
2279
+
2280
  async def query_with_keywords(
2281
  query: str,
2282
  prompt: str,