my chunker keeps cutting tables in half and then the model makes up the column names (llama 3.1 8b local, 3060 12gb)
so basically i built a little thing that reads the manuals for my dads workshop machines and answers questions about them. mostly it works! but anything where the answer lives in a table comes back wrong, or half right which is worse. i dumped the chunks out to a text file and had a proper look. one of them ends halfway down a torque spec table and the next one starts with the rest of the rows and no header on it. so the model gets handed a column of numbers with nothing saying what the numbers are, and it decides what they are. it told me 40 Nm for something that is 4.0 Nm in the actual manual, which on a workshop machine is not a rounding problem. i'm on 1000 characters with 200 overlap because that's what the tutorial i followed had in it. EDIT: bumped the overlap to 400 and the torque table is fine now. chunk count nearly doubled and my embed pass went from 4 mins to 11, which i do not care about, it's a one off. two other tables are still split though because they're longer than 1000 characters all on their own. EDIT 2: right, 2000 character chunks doesnt fix it either, one of these tables is a full page. so what i think i actually want is for it to never cut a table at all, and to staple the header back onto every piece when it has to. is that a prompt thing or am i writing actual code quick q, unrelated, what is everyone using to read pdfs that have the text in two columns. mine reads straight across both columns and comes out as nonsense
Not run against a model yet
0 works · 1 fails
Times copied by users
Problem Instructions
answers about a torque spec have to come back with the unit attached to the right number, which means the table the number lives in cannot arrive with its header cut off. prompt side or code side, i don't mind which, i just need it to stop!
- •no answer returns 40 Nm where the manual prints 4.0 Nm
- •every chunk that contains table rows carries that table's header row
- •the two tables that are longer than 1000 characters on their own come back whole, or come back in pieces that each keep the header
- •answers name the row they came from so i can check them against the manual without reading the whole chunk
Response contract
Reply with one JSON object and nothing else. No prose before it, no markdown fence, no text after the closing brace.
{
"passages": [
{
"id": "string", // passage id exactly as printed in its banner, unaltered
"class": "string", // PROSE, COMPLETE_TABLE, HEAD_FRAGMENT or TAIL_FRAGMENT
"columns": 0 // cells in one row of this passage's table, 0 for PROSE
}
], // one entry per passage supplied, in the order supplied
"header_source": "string", // VERBATIM, INFERRED or NONE, for the labels attached to the TAIL_FRAGMENT
"header_from": "string", // id of the passage the labels were copied from, empty string unless header_source is VERBATIM
"header_labels": ["string"], // labels in column order, copied character for character, empty array unless header_source is VERBATIM
"answer": "string", // the one requested cell, copied character for character with its decimal point and any trailing zero, empty string when no answer is permitted
"answer_from": "string", // id of the passage the answer cell was read from, empty string when answer is empty
"unanswerable_reason": "string" // code and clause, see NO ANSWER, empty string when answer is non-empty
}
CLASSIFYING. Test every supplied passage in this order and stop at the first test that fits.
TAIL_FRAGMENT: the passage has table rows and no label row stands above them inside this same passage.
HEAD_FRAGMENT: a label row is present and the last line of the passage is a table row.
COMPLETE_TABLE: a label row is present and at least one line that is not a table row follows the last table row inside this same passage.
PROSE: no table rows.
LABELS. INFERRED is never a permitted outcome. You may not name a column from the size of its values, from a unit, from what a table of this kind usually holds, or from the wording of the question. Either the labels are copied character for character from another passage under the join rule, which makes header_source VERBATIM, or there are no labels, which makes header_source NONE with header_from "" and header_labels []. If no passage is classed TAIL_FRAGMENT, header_source is NONE.
JOIN RULE. For a passage T classed TAIL_FRAGMENT, the only candidate header H is the nearest passage above T in the supplied order that is classed HEAD_FRAGMENT. Labels may be copied from H onto T only when all four of these hold:
J1 H exists.
J2 H and T report the same columns count.
J3 the banners of H and T name the same source.
J4 the chunk number in H's banner is exactly one less than the chunk number in T's banner.
Any one of the four failing means no join, whatever the labels look like. A near match is not a match.
ANSWERING. The document carries one question. A cell may be read only from a passage classed COMPLETE_TABLE, or from a fragment T that was joined under the rule above. A passage classed PROSE is never a source for an answer, whatever number it prints. A table answers the question only when the caption or heading printed with that table names the same equipment the question names; a table belonging to another model or another unit does not answer it. Do not round, do not convert, do not tidy a value that looks odd.
NO ANSWER. When no cell may be read, answer and answer_from are "" and unanswerable_reason is one clause of at most 160 characters starting with one of these codes and a colon: NOT_A_HEAD, COLUMN_COUNT, SOURCE_MISMATCH, CHUNK_GAP, NO_MATCHING_TABLE. Use the code of the first join condition that failed, taking J1 to J4 in that order, and use NO_MATCHING_TABLE only when no join was attempted at all. Where a chunk is absent, name it in the clause as source#number, in the shape brayton_manual.txt#7.