[Bug]: TextChunk.start_char/end_char are wrong for overlapping token chunks (and for SentenceChunker in some cases)

Đang mở
#2,595 1 bình luận 0 reaction 0 người được giao Xem trên GitHub

Maintainer thường phản hồi trong vòng 5 ngày

Chưa có ai nhận issue này.

Đánh giá

Độ khó
3/5
Thời gian dự kiến
1-2 ngày
Mức phù hợp với người mới
52/100
Loại issue
Lỗi
Độ rõ ràng
Khá rõ ràng
Mức độ hoạt động
Sôi nổi
Công nghệ
python
Lĩnh vực
data

Hướng nghiên cứu

Start in packages/graphrag-chunking: create_chunk_results.py assigns start_char from the previous end_char, which is wrong for TokenChunker's overlapping windows in token_chunker.py. The SentenceChunker correction in sentence_chunker.py uses text.find on the transformed text. Run the TokenChunker snippet from the issue and check that text[start_char:end_char+1] equals original. Done means the offsets match for overlapping and transformed chunks, or the docstring in text_chunk.py states they only hold for non-overlapping chunks. The maintainers still need to choose between the two.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

Do you need to file an issue?
  • I have searched the existing issues and this bug is not already filed.
  • My model is hosted on OpenAI or Azure. If not, please look at the "model providers" issue and don't file a new one here. (Not applicable: the bug is in chunking, before any model call.)
  • I believe this is a legitimate bug, not just a question. If this is a question, please use the Discussions area.
Describe the bug

TextChunk.start_char / end_char are documented as the position of the raw chunk text in the source document (text_chunk.py). Severity is low: nothing else in packages/graphrag reads these fields (I grepped for start_char / end_char outside graphrag-chunking), so current indexing output is not affected. It is a wrong value in a public data class.

  1. TokenChunker with overlap (the case I ran). create_chunk_results (create_chunk_results.py#L18-L31) sets each start_char to the previous end_char + 1, i.e. it assumes the chunks are consecutive and non-overlapping. TokenChunker passes it overlapping windows (token_chunker.py#L42, default overlap 100), so every chunk after the first drifts by about overlap * index and end_char can run past the end of the text.

  2. SentenceChunker with a transform (checked with a stubbed splitter only). SentenceChunker.chunk (sentence_chunker.py#L35-L47) corrects offsets with text.find(result.text, start). result.text is the transformed text (e.g. with prepend_metadata), so find returns -1, delta is negative, and the delta > 0 guard silently skips the correction. Using result.original would match the source.

  3. SentenceChunker with repeated sentences (weakest of the three). The correction only bumps results[index + 1], not later chunks, so for repeated sentences separated by wide whitespace find can match an earlier occurrence.

I did not have nltk installed, so cases 2 and 3 were checked by reading the code and running it with a stubbed sent_tokenize, not against the real tokenizer. Case 1 was run as shown below.

Steps to reproduce
from graphrag_chunking.token_chunker import TokenChunker

enc = lambda s: [ord(c) for c in s]
dec = lambda t: "".join(map(chr, t))
text = "abcdefghijklmnopqrstuvwxyz"
for c in TokenChunker(size=10, overlap=4, encode=enc, decode=dec).chunk(text):
    print(c.start_char, c.end_char, repr(text[c.start_char:c.end_char + 1]), repr(c.original))

Output:

0 9 'abcdefghij' 'abcdefghij'
10 19 'klmnopqrst' 'ghijklmnop'     <- true span is 6..15
20 29 'uvwxyz' 'mnopqrstuv'          <- true span is 12..21
30 37 '' 'stuvwxyz'                  <- start is past the end of the text

For case 2, with the splitter stubbed: "One. Two. Three." with add_metadata({"t": "x"}) gives 'Two.' the span (4, 7), which slices ' Two'. For case 3, "Go. Go. Go. Go." gives spans (0,2), (6,8), (12,14), (12,14); the 4th duplicates the 3rd and its correct start is 18.

Expected Behavior

text[chunk.start_char : chunk.end_char + 1] == chunk.original when the chunker does not strip or alter the text.

GraphRAG Config Used
chunking:
  type: tokens
  size: 1200
  overlap: 100

(Library-level behaviour; the repro calls the chunker directly with small values.)

Logs and screenshots

No errors; the offsets are just wrong.

Additional Information
  • GraphRAG Version: 3.3.0 (graphrag-chunking at 5faaaf4f)
  • Operating System: macOS
  • Python Version: 3.11
  • Related Issues: #2589 (another TokenChunker defect, about decoding at token boundaries)

Possible fix: have split_text_on_tokens also return the real character offset of each window (e.g. the length of decode(tokens[:start_idx])), and in SentenceChunker use a running cursor with text.find(result.original, cursor). If the maintainers consider the offsets unused and not worth fixing, documenting that they are only valid for non-overlapping chunks would also resolve this.

Ngôn ngữ chính
Python
Star
36.6k
Fork
3.9k
Merge trung bình
4 ngày 11 giờ
Pull request đã merge (30 ngày)
1

Chuẩn bị môi trường

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của microsoft/graphrag

Tất cả issue của microsoft/graphrag

Issue tương tự

Thêm issue về Python

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.