Stay Ahead, Stay ONMINE

Retrieve One Row from a Table, Not the Whole Table: Row-Level Chunks for RAG

A car-insurance contract prints its guarantees as a 40-row table: one row per covered event, with columns for the event, its cap, its deductible, and the eligibility condition. A user opens the search bar and asks “what is the cap for vehicle theft?”. The naive retrieval move indexes the whole table as one chunk. When the question matches, the generation model receives 39 rows of unrelated events on top of the one that answers, and has to guess which line the reader meant. Sending the whole table makes the model do the filtering the retriever should have done, and the unit that actually matches the question is one row, not the whole rectangle.This article is part of Part II of Enterprise Document Intelligence, a series that builds an enterprise RAG system from four bricks. The retrieval brick treats retrieval as filtering rather than vector search, runs keyword and embedding signals in parallel, lets an LLM arbiter rank the finalists, and routes long documents through their table of contents. This companion handles the case they leave open: a document whose answer lives inside a table, where the unit that fits the question is one row.🧭 New to the series? Start with the map: Prompt, Context, Loop sets out the three engineering layers every RAG system is built on, the prompt (the call itself), the context (what fills the model’s window), the loop (when the next call fires and when it stops), and walks the whole series through that lens, article by article. It is the shortest way to see what is covered and where this one sits.Article 7sexies sits in Part II as a retrieval companion. – Image by author📓 The runnable companion is on GitHub: load Table 1 of the Attention paper, watch serialize_table_rows turn it into four row-level chunks, then run a targeted keyword query and see it return the one row instead of the whole table. On GitHub: doc-intel/notebooks-vol1.The public companion-code repo at doc-intel/notebooks-vol1 – Image by authorWe work through this on Attention Is All You Need (Vaswani et al. 2017; arXiv non-exclusive distribution license, declared on the arXiv abstract page). Its Table 1 (page 6) is a compact real-world case: four rows, four columns, every row is a different answer. Runnable code paths call OpenAI services governed by OpenAI’s Terms of Use. Parsing uses Docling (MIT license).1. Table vs row: the unit of retrievalA table on paper is a bounded region: a rectangle of cells with a header row on top and body rows below. A retrieval system that treats the whole rectangle as one chunk collapses that structure. The chunk either matches (and the generation model receives every row, most of them irrelevant to the question) or it does not (and the generation model receives nothing, because the one relevant row is buried under all the other rows the scorer had to average over).The mismatch is between the document’s unit of information (one rectangle) and the reader’s unit of question (one row). A question like “cap for vehicle theft?” asks about one row. A question like “which events are covered?” asks about the whole rectangle. Both are legitimate. A retrieval brick that only offers the rectangle answers the second question and mishandles the first.The fix is not to pick one scale over the other, but to make both scales available and let the dispatcher pick. That is what this article builds, on top of the parsing brick’s existing output.2. Building the row-level indexTwo steps turn a parsed table into a retrievable index: read the shape the parser emits, then serialize each body row into its own chunk.2.1 What the parser already emitsDocling and Azure Document Intelligence both emit tables as markdown-pipe lines inside line_df. A table with 4 body rows becomes 6 lines: a header row (| Col1 | Col2 | … |), a separator row (| — | — | … |), and one body row per data row, in reading order. No extra _type column survives the public line_df contract. The pipe pattern in text is the signal.The pipe format is the parser’s contract for a table, and what the row-level serializer reads. – Image by authorThe rules of the pipe format are the same across docling and Azure Layout, and light enough to detect without a per-parser branch:A pipe row starts and ends with |, with at least one interior pipe.The separator row (interior of dashes, colons and pipes) marks the split between the header and the body.Consecutive pipe rows on the same page, or across an immediate page break, belong to the same table.Anything else, including a non-pipe line in between, resets the group.The four rules above are the whole contract. The row-level primitive below reads only line_df and needs nothing else from the parser.2.2 One chunk per table rowThe serialize_table_rows function turns each body row of every table into a retrievable chunk. A pandas.DataFrame in, a pandas.DataFrame out, the same shape Article 7B’s retriever uses, so the two bricks compose over the one line_df. The whole function is a small scan: group the pipe lines into tables, read the header off the row above the separator, and emit one output row per body line.def serialize_table_rows(line_df: pd.DataFrame) – > pd.DataFrame: “””One retrievable chunk per body row of every table.””” lines = line_df.sort_values([“page_num”, “line_num”]) tables = group_contiguous_pipe_rows(lines) # runs of | … | lines out = [] for tid, table in enumerate(tables, start=1): sep = first_separator_row(table) # the | — | — | line headers = split_cells(table[sep – 1]) # the row above the separator headers, body = fold_multirow_header(headers, table[sep + 1:]) for row_idx, line in enumerate(body): cells = split_cells(line.text) out.append({ “table_id”: f”t{tid}”, “page_num”: line.page_num, “line_num”: line.line_num, “column_headers”: headers, “row_cells”: cells, # headers travel with the values, so a match reads like a sentence “row_serialized”: ” | “.join(f”{h}: {c}” for h, c in zip(headers, cells)), }) return pd.DataFrame(out)The function returns a new frame, not a mutation of line_df. The parsing brick’s frame stays the point of truth for the document’s geometry (bbox, position, page); the row-level frame is a second index on top of it. Downstream retrievers that never enable row-level indexing keep working unchanged. The ones that do read the second frame explicitly, so nobody has to check a chunk_type tag.The serialization format. Each body row becomes col: val | col: val | …. The choice is deliberate: an LLM reads that shape as naturally as a paragraph, and the retriever that keyword-matches or embeds paragraphs today can index row_serialized values with no change. The reader who receives a match sees a self-explaining line (the column names travel with the values) instead of a naked cell.Column-value pairs also compose with the standard citation contract from Article 8. When the generation model quotes a specific value, the quote lands on the body row’s (page_num, line_num), exactly like any other span.3. Retrieving at two scalesThe row-level index is a second scale, not a replacement. The dispatcher picks the scale from the question, and two worked examples (the guarantees table from the intro, then a real published paper) show the payoff.3.1 Two scales, one dispatcherThree question shapes cover most of what users ask a table, and each maps to a scale.Targeted lookup (“cap for vehicle theft?”, “BLEU for the Transformer big model?”, “salary of the deputy CFO?”). Route to the row-level index. Return one row plus its column headers. Generation receives exactly what it needs.Synthesis (“which events are covered?”, “what layer types does the paper compare?”, “list every executive on the compensation grid?”). Row-level still fires, but every row of the same table matches. The dispatcher notices the shared table_id and widens back to the whole table before generation.Mixed (“summarise the vehicle-theft cap and compare it with the fire cap”). Two rows on the same table, generation stitches the answer from both. The row-level index makes this cheap; a whole-table dump would have worked too, but at a higher token cost.Row granularity is a second scale, not a replacement, chosen by the dispatcher from question shape. – Image by authorThe widening rule from row-level to whole-table is worth naming: when k body rows of the same table_id all match the question, and k covers most of the table, treat the match as table-level. In practice, a threshold like k / n_body_rows ≥ 0.6 catches synthesis queries. Below that threshold, the row-level answer is the honest one. A synthesis pretending to summarise on the strength of 2 out of 40 rows would be a hallucination the arbiter of Article 7C should already refuse.3.2 The guarantees table from the introBack to the car-insurance contract that opened this article. Its guarantees table has one row per covered event and four columns: the event, its cap, its deductible, and the eligibility condition. Here is a slice of it (the full contract runs to about forty rows).The guarantees table from the intro, a slice of the full contract. – Image by authorThe question from the intro, “what is the cap for vehicle theft?”, is a targeted lookup. Serialize the table, then keyword-match on the serialized rows.row_df = serialize_table_rows(line_df) # one chunk per body rowhit = row_df[row_df[“row_serialized”].str.contains(“Vehicle theft”)]# 1 row, 122 chars:# “Covered event: Vehicle theft | Cap: 25,000 EUR |# Deductible: 500 EUR | Eligibility condition: Tracker installed and active”The match returns one row of 122 characters: the Vehicle theft event with its cap, deductible and condition, nothing else. The whole eight-row slice is 943 characters, a 7.7× ratio already. On the full forty-row contract the same single-row answer is roughly a 40× saving, since the ratio is just the row count. The generation model reads the one line it needs, so it cannot answer with the fire cap or the vandalism deductible by mistake.3.3 The same on a real PDF: the Attention paperThe guarantees table is hand-built to match the intro; here is the same mechanism on a real published PDF. The Attention paper has four tables. Table 1 on page 6 is the compact case that shows the mechanism end to end. It has four body rows, one per layer type: Self-Attention, Recurrent, Convolutional, Self-Attention (restricted). The columns are Layer Type, Complexity per Layer, Sequential Operations, Maximum Path Length. Here it is as printed in the paper:The actual Table 1 the parser reads, straight from the PDF. – Image by author (crop of arXiv:1706.03762v7, page 6, under the arXiv non-exclusive distribution license)Two questions test the two scales.Every layer type is a distinct chunk; Self-Attention is the accent line. – Image by authorTargeted query. “What is the complexity of self-attention per layer?”. Keyword-match on row_serialized returns the Self-Attention row (page 6, line 4), 124 characters of context. A looser match also surfaces the Self-Attention (restricted) variant on line 7; either way the retriever hands back the one or two rows that match, not the whole rectangle. The whole Table 1 is four rows totalling 528 characters, a 4.3× ratio for the single-row hit on this compact four-row table. The gap tracks the row count, the same way it did on the guarantees table in the previous section.Synthesis query. “What layer types are compared?”. Keyword-match on Layer Type: returns four hits, all on table_id = t1. Every row of the table matches, so the dispatcher widens back to the whole table. Same outcome as a table-level retriever, no regression.Context-size ratio measured on Attention Table 1; the gap scales with the number of rows. – Image by author4. Edge cases and pipeline wiringTwo practical concerns remain: the one table shape the serializer has to handle itself, and how the row-level index plugs into the existing retriever.Real parsers do not always produce a single header row. On the Attention paper Table 2 (page 8, BLEU and Training Cost), the printed header spans two lines: Model / BLEU / Training Cost on top, then EN-DE / EN-FR under both BLEU and Training Cost. Docling flattens that into a first pipe row with blank cells (Model, BLEU, , `Training Cost (FLOPs)`,), a separator, then a body row that is really the second header line, before the numbers begin.A single-line serializer reads the flattened first row as the header and the second header line as the first body row. A keyword search for EN-DE then hits that label-only row before the numeric rows below it. This is the one table shape the primitive has to handle itself, because it is common and the failure is silent.The fix stays inside the serializer, in the fold_multirow_header step the core loop already calls. The signal is the blank cell: a header cell is empty only when the parser flattened a cell that spanned several columns. When that happens, forward-fill the spanned label rightward, then check whether the first body row is really a sub-header (all labels, no digits, with real numbers on the row below). If it is, concatenate the two header levels column by column and drop the sub-header line from the body.def fold_multirow_header(headers, body): “””Fold a spanned two-line header into one labelled header row.””” if “” not in headers or len(body) < 2: # nothing to fold return headers, body headers = forward_fill(headers) # a merged cell blanks the columns it spans subline = split_cells(body[0].text) is_subheader = ( len(subline) == len(headers) and not any(has_digit(c) for c in subline) # all labels and any(has_digit(c) for c in split_cells(body[1].text)) # numbers below ) if is_subheader: headers = [f"{t} {s}".strip() for t, s in zip(headers, subline)] body = body[1:] # the sub-header line is not a data row return headers, bodyOn the real docling parse of Table 2, this turns the header into Model, BLEU EN-DE, BLEU EN-FR, Training Cost (FLOPs) EN-DE, Training Cost (FLOPs) EN-FR, drops the label-only line, and serializes the numeric rows against the merged labels. A search for EN-DE now lands on the data rows, where it belongs.The guard is what makes this safe to run on every table. It fires only when the header carries a blank cell and the suspected sub-header is all text and the row beneath it carries digits. An ordinary single-line-header table, or an all-text glossary table, keeps every body row untouched. Upstream is still the better place to normalise multi-row headers, since a parser that emits one logical header row fixes it for every consumer, not just retrieval. Until that lands, the serializer no longer breaks silently on the shape.4.2 Where it plugs into the pipelineThe row-level frame is the parallel index from section 2.2, wired into the retriever by a single activation.row_df = serialize_table_rows(line_df) is computed once and cached next to line_df (output//parsing/row_df.parquet).The retriever gains a use_row_level: bool flag alongside use_toc, use_keywords, use_dense. On, the row-level frame is indexed with the same keyword and embedding primitives that already run on paragraphs.The question parser (Article 6) sets the flag by question shape: targeted_lookup on a document with tables turns it on, synthesis leaves it off, mixed turns it on and lets the widening rule from section 3.1 do the fusion.Nothing about the paragraph-level retriever changes.SummaryTables in a document carry structured information that a paragraph-level retriever averages away. This article added a second retrieval scale on top of the existing line_df contract: serialize_table_rows(line_df) → row_df turns each body row of every detected table into a chunk paired with its column headers, keyed on (page_num, line_num) for citation. The dispatcher picks the scale by question shape. Targeted queries route to row-level, synthesis queries widen back to the whole table, mixed queries stitch two or three rows. On a slice of the insurance guarantees table a targeted lookup returns one 122-character row where the whole slice is 943, and on the Attention paper Table 1 the same move sends 124 characters against 528; the ratio is about the row count, so a full contract saves far more. Multi-row headers, the one shape a single-line serializer gets wrong, are folded inside the serializer: a spanned header is forward-filled and its sub-header line concatenated into one labelled row, guarded so an ordinary table is never touched. The row index sits alongside line_df, not inside it. The parsing brick’s contract is untouched, and every existing consumer of line_df keeps working unchanged.Sources and further readingDocling documentation, table structure preservation: docling-project/docling.Vaswani, A. et al. Attention Is All You Need. arXiv:1706.03762, 2017. arxiv.org/abs/1706.03762. Table 1 (page 6, layer complexity) and Table 2 (page 8, BLEU and Training Cost) are the worked examples of this article.serialize_table_rows, the row-level serializer, with its test suite, ships in the companion notebooks repository (doc-intel/notebooks-vol1).Reproducible probe: scripts/dev/probe_row_level_retrieval.py regenerates the cached row_df_docling.parquet used in the worked example and the multi-row-header fix.Earlier in the series (the ones still earning, worth the click):RetrievalLoop engineering for cross-references: when RAG answers ‘see Section 7.2’ instead of the actual answer. Another question shape that needs its own retrieval unit.Prompt engineering isn’t enough: four bricks of context engineering stop RAG hallucinations. What a retrieved row becomes once it reaches generation.Parsing, upstream of retrievalBefore full agentic RAG: know how you decide, and the parsing methods you pick from. Where the table structure this article reads comes from.The pipelineRAG workflow and loop engineering: the dispatcher that decides when to loop and when to stop. The dispatcher that turns row-level retrieval on and off.

A car-insurance contract prints its guarantees as a 40-row table: one row per covered event, with columns for the event, its cap, its deductible, and the eligibility condition. A user opens the search bar and asks “what is the cap for vehicle theft?”. The naive retrieval move indexes the whole table as one chunk. When the question matches, the generation model receives 39 rows of unrelated events on top of the one that answers, and has to guess which line the reader meant. Sending the whole table makes the model do the filtering the retriever should have done, and the unit that actually matches the question is one row, not the whole rectangle.

This article is part of Part II of Enterprise Document Intelligence, a series that builds an enterprise RAG system from four bricks. The retrieval brick treats retrieval as filtering rather than vector search, runs keyword and embedding signals in parallel, lets an LLM arbiter rank the finalists, and routes long documents through their table of contents. This companion handles the case they leave open: a document whose answer lives inside a table, where the unit that fits the question is one row.

🧭 New to the series? Start with the map: Prompt, Context, Loop sets out the three engineering layers every RAG system is built on, the prompt (the call itself), the context (what fills the model’s window), the loop (when the next call fires and when it stops), and walks the whole series through that lens, article by article. It is the shortest way to see what is covered and where this one sits.

Article 7sexies sits in Part II as a retrieval companion. – Image by author

📓 The runnable companion is on GitHub: load Table 1 of the Attention paper, watch serialize_table_rows turn it into four row-level chunks, then run a targeted keyword query and see it return the one row instead of the whole table. On GitHub: doc-intel/notebooks-vol1.

The public companion-code repo at doc-intel/notebooks-vol1 – Image by author

We work through this on Attention Is All You Need (Vaswani et al. 2017; arXiv non-exclusive distribution license, declared on the arXiv abstract page). Its Table 1 (page 6) is a compact real-world case: four rows, four columns, every row is a different answer. Runnable code paths call OpenAI services governed by OpenAI’s Terms of Use. Parsing uses Docling (MIT license).

1. Table vs row: the unit of retrieval

A table on paper is a bounded region: a rectangle of cells with a header row on top and body rows below. A retrieval system that treats the whole rectangle as one chunk collapses that structure. The chunk either matches (and the generation model receives every row, most of them irrelevant to the question) or it does not (and the generation model receives nothing, because the one relevant row is buried under all the other rows the scorer had to average over).

The mismatch is between the document’s unit of information (one rectangle) and the reader’s unit of question (one row). A question like “cap for vehicle theft?” asks about one row. A question like “which events are covered?” asks about the whole rectangle. Both are legitimate. A retrieval brick that only offers the rectangle answers the second question and mishandles the first.

The fix is not to pick one scale over the other, but to make both scales available and let the dispatcher pick. That is what this article builds, on top of the parsing brick’s existing output.

2. Building the row-level index

Two steps turn a parsed table into a retrievable index: read the shape the parser emits, then serialize each body row into its own chunk.

2.1 What the parser already emits

Docling and Azure Document Intelligence both emit tables as markdown-pipe lines inside line_df. A table with 4 body rows becomes 6 lines: a header row (| Col1 | Col2 | ... |), a separator row (| --- | --- | ... |), and one body row per data row, in reading order. No extra _type column survives the public line_df contract. The pipe pattern in text is the signal.

The pipe format is the parser’s contract for a table, and what the row-level serializer reads. – Image by author

The rules of the pipe format are the same across docling and Azure Layout, and light enough to detect without a per-parser branch:

  • A pipe row starts and ends with |, with at least one interior pipe.

  • The separator row (interior of dashes, colons and pipes) marks the split between the header and the body.

  • Consecutive pipe rows on the same page, or across an immediate page break, belong to the same table.

  • Anything else, including a non-pipe line in between, resets the group.

The four rules above are the whole contract. The row-level primitive below reads only line_df and needs nothing else from the parser.

2.2 One chunk per table row

The serialize_table_rows function turns each body row of every table into a retrievable chunk. A pandas.DataFrame in, a pandas.DataFrame out, the same shape Article 7B’s retriever uses, so the two bricks compose over the one line_df. The whole function is a small scan: group the pipe lines into tables, read the header off the row above the separator, and emit one output row per body line.

def serialize_table_rows(line_df: pd.DataFrame) -> pd.DataFrame:    """One retrievable chunk per body row of every table."""    lines = line_df.sort_values(["page_num", "line_num"])    tables = group_contiguous_pipe_rows(lines)   # runs of | ... | lines    out = []    for tid, table in enumerate(tables, start=1):        sep = first_separator_row(table)         # the | --- | --- | line        headers = split_cells(table[sep - 1])    # the row above the separator        headers, body = fold_multirow_header(headers, table[sep + 1:])        for row_idx, line in enumerate(body):            cells = split_cells(line.text)            out.append({                "table_id": f"t{tid}",                "page_num": line.page_num, "line_num": line.line_num,                "column_headers": headers, "row_cells": cells,                # headers travel with the values, so a match reads like a sentence                "row_serialized":                    " | ".join(f"{h}: {c}" for h, c in zip(headers, cells)),            })    return pd.DataFrame(out)

The function returns a new frame, not a mutation of line_df. The parsing brick’s frame stays the point of truth for the document’s geometry (bbox, position, page); the row-level frame is a second index on top of it. Downstream retrievers that never enable row-level indexing keep working unchanged. The ones that do read the second frame explicitly, so nobody has to check a chunk_type tag.

The serialization format. Each body row becomes col: val | col: val | .... The choice is deliberate: an LLM reads that shape as naturally as a paragraph, and the retriever that keyword-matches or embeds paragraphs today can index row_serialized values with no change. The reader who receives a match sees a self-explaining line (the column names travel with the values) instead of a naked cell.

Column-value pairs also compose with the standard citation contract from Article 8. When the generation model quotes a specific value, the quote lands on the body row’s (page_num, line_num), exactly like any other span.

3. Retrieving at two scales

The row-level index is a second scale, not a replacement. The dispatcher picks the scale from the question, and two worked examples (the guarantees table from the intro, then a real published paper) show the payoff.

3.1 Two scales, one dispatcher

Three question shapes cover most of what users ask a table, and each maps to a scale.

  • Targeted lookup (“cap for vehicle theft?”, “BLEU for the Transformer big model?”, “salary of the deputy CFO?”). Route to the row-level index. Return one row plus its column headers. Generation receives exactly what it needs.

  • Synthesis (“which events are covered?”, “what layer types does the paper compare?”, “list every executive on the compensation grid?”). Row-level still fires, but every row of the same table matches. The dispatcher notices the shared table_id and widens back to the whole table before generation.

  • Mixed (“summarise the vehicle-theft cap and compare it with the fire cap”). Two rows on the same table, generation stitches the answer from both. The row-level index makes this cheap; a whole-table dump would have worked too, but at a higher token cost.

Row granularity is a second scale, not a replacement, chosen by the dispatcher from question shape. – Image by author

The widening rule from row-level to whole-table is worth naming: when k body rows of the same table_id all match the question, and k covers most of the table, treat the match as table-level. In practice, a threshold like k / n_body_rows ≥ 0.6 catches synthesis queries. Below that threshold, the row-level answer is the honest one. A synthesis pretending to summarise on the strength of 2 out of 40 rows would be a hallucination the arbiter of Article 7C should already refuse.

3.2 The guarantees table from the intro

Back to the car-insurance contract that opened this article. Its guarantees table has one row per covered event and four columns: the event, its cap, its deductible, and the eligibility condition. Here is a slice of it (the full contract runs to about forty rows).

The guarantees table from the intro, a slice of the full contract. – Image by author

The question from the intro, “what is the cap for vehicle theft?”, is a targeted lookup. Serialize the table, then keyword-match on the serialized rows.

row_df = serialize_table_rows(line_df)          # one chunk per body rowhit = row_df[row_df["row_serialized"].str.contains("Vehicle theft")]# 1 row, 122 chars:#   "Covered event: Vehicle theft | Cap: 25,000 EUR |#    Deductible: 500 EUR | Eligibility condition: Tracker installed and active"

The match returns one row of 122 characters: the Vehicle theft event with its cap, deductible and condition, nothing else. The whole eight-row slice is 943 characters, a 7.7× ratio already. On the full forty-row contract the same single-row answer is roughly a 40× saving, since the ratio is just the row count. The generation model reads the one line it needs, so it cannot answer with the fire cap or the vandalism deductible by mistake.

3.3 The same on a real PDF: the Attention paper

The guarantees table is hand-built to match the intro; here is the same mechanism on a real published PDF. The Attention paper has four tables. Table 1 on page 6 is the compact case that shows the mechanism end to end. It has four body rows, one per layer type: Self-Attention, Recurrent, Convolutional, Self-Attention (restricted). The columns are Layer Type, Complexity per Layer, Sequential Operations, Maximum Path Length. Here it is as printed in the paper:

The actual Table 1 the parser reads, straight from the PDF. – Image by author (crop of arXiv:1706.03762v7, page 6, under the arXiv non-exclusive distribution license)

Two questions test the two scales.

Every layer type is a distinct chunk; Self-Attention is the accent line. – Image by author

Targeted query. “What is the complexity of self-attention per layer?”. Keyword-match on row_serialized returns the Self-Attention row (page 6, line 4), 124 characters of context. A looser match also surfaces the Self-Attention (restricted) variant on line 7; either way the retriever hands back the one or two rows that match, not the whole rectangle. The whole Table 1 is four rows totalling 528 characters, a 4.3× ratio for the single-row hit on this compact four-row table. The gap tracks the row count, the same way it did on the guarantees table in the previous section.

Synthesis query. “What layer types are compared?”. Keyword-match on Layer Type: returns four hits, all on table_id = t1. Every row of the table matches, so the dispatcher widens back to the whole table. Same outcome as a table-level retriever, no regression.

Context-size ratio measured on Attention Table 1; the gap scales with the number of rows. – Image by author

4. Edge cases and pipeline wiring

Two practical concerns remain: the one table shape the serializer has to handle itself, and how the row-level index plugs into the existing retriever.

Real parsers do not always produce a single header row. On the Attention paper Table 2 (page 8, BLEU and Training Cost), the printed header spans two lines: Model / BLEU / Training Cost on top, then EN-DE / EN-FR under both BLEU and Training Cost. Docling flattens that into a first pipe row with blank cells (Model, BLEU, , `Training Cost (FLOPs)`,), a separator, then a body row that is really the second header line, before the numbers begin.

A single-line serializer reads the flattened first row as the header and the second header line as the first body row. A keyword search for EN-DE then hits that label-only row before the numeric rows below it. This is the one table shape the primitive has to handle itself, because it is common and the failure is silent.

The fix stays inside the serializer, in the fold_multirow_header step the core loop already calls. The signal is the blank cell: a header cell is empty only when the parser flattened a cell that spanned several columns. When that happens, forward-fill the spanned label rightward, then check whether the first body row is really a sub-header (all labels, no digits, with real numbers on the row below). If it is, concatenate the two header levels column by column and drop the sub-header line from the body.

def fold_multirow_header(headers, body):    """Fold a spanned two-line header into one labelled header row."""    if "" not in headers or len(body) < 2:   # nothing to fold        return headers, body    headers = forward_fill(headers)      # a merged cell blanks the columns it spans    subline = split_cells(body[0].text)    is_subheader = (        len(subline) == len(headers)        and not any(has_digit(c) for c in subline)               # all labels        and any(has_digit(c) for c in split_cells(body[1].text)) # numbers below    )    if is_subheader:        headers = [f"{t} {s}".strip() for t, s in zip(headers, subline)]        body = body[1:]                  # the sub-header line is not a data row    return headers, body

On the real docling parse of Table 2, this turns the header into Model, BLEU EN-DE, BLEU EN-FR, Training Cost (FLOPs) EN-DE, Training Cost (FLOPs) EN-FR, drops the label-only line, and serializes the numeric rows against the merged labels. A search for EN-DE now lands on the data rows, where it belongs.

The guard is what makes this safe to run on every table. It fires only when the header carries a blank cell and the suspected sub-header is all text and the row beneath it carries digits. An ordinary single-line-header table, or an all-text glossary table, keeps every body row untouched. Upstream is still the better place to normalise multi-row headers, since a parser that emits one logical header row fixes it for every consumer, not just retrieval. Until that lands, the serializer no longer breaks silently on the shape.

4.2 Where it plugs into the pipeline

The row-level frame is the parallel index from section 2.2, wired into the retriever by a single activation.

  • row_df = serialize_table_rows(line_df) is computed once and cached next to line_df (output//parsing/row_df.parquet).

  • The retriever gains a use_row_level: bool flag alongside use_toc, use_keywords, use_dense. On, the row-level frame is indexed with the same keyword and embedding primitives that already run on paragraphs.

  • The question parser (Article 6) sets the flag by question shape: targeted_lookup on a document with tables turns it on, synthesis leaves it off, mixed turns it on and lets the widening rule from section 3.1 do the fusion.

Nothing about the paragraph-level retriever changes.

Summary

Tables in a document carry structured information that a paragraph-level retriever averages away. This article added a second retrieval scale on top of the existing line_df contract: serialize_table_rows(line_df) → row_df turns each body row of every detected table into a chunk paired with its column headers, keyed on (page_num, line_num) for citation. The dispatcher picks the scale by question shape. Targeted queries route to row-level, synthesis queries widen back to the whole table, mixed queries stitch two or three rows. On a slice of the insurance guarantees table a targeted lookup returns one 122-character row where the whole slice is 943, and on the Attention paper Table 1 the same move sends 124 characters against 528; the ratio is about the row count, so a full contract saves far more. Multi-row headers, the one shape a single-line serializer gets wrong, are folded inside the serializer: a spanned header is forward-filled and its sub-header line concatenated into one labelled row, guarded so an ordinary table is never touched. The row index sits alongside line_df, not inside it. The parsing brick’s contract is untouched, and every existing consumer of line_df keeps working unchanged.

Sources and further reading

  • Docling documentation, table structure preservation: docling-project/docling.

  • Vaswani, A. et al. Attention Is All You Need. arXiv:1706.03762, 2017. arxiv.org/abs/1706.03762. Table 1 (page 6, layer complexity) and Table 2 (page 8, BLEU and Training Cost) are the worked examples of this article.

  • serialize_table_rows, the row-level serializer, with its test suite, ships in the companion notebooks repository (doc-intel/notebooks-vol1).

  • Reproducible probe: scripts/dev/probe_row_level_retrieval.py regenerates the cached row_df_docling.parquet used in the worked example and the multi-row-header fix.

Earlier in the series (the ones still earning, worth the click):

Retrieval

Parsing, upstream of retrieval

The pipeline

Shape
Shape
Stay Ahead

Explore More Insights

Stay ahead with more perspectives on cutting-edge power, infrastructure, energy,  bitcoin and AI solutions. Explore these articles to uncover strategies and insights shaping the future of industries.

Shape

Cisco taps Teleport for infrastructure identity management tech

Cisco is continuing to embed identity management capabilities deeper into its product portfolio by teaming with Teleport, a security vendor headquartered in Oakland, Calif., that’s focused on identity-based infrastructure access management. Cisco is investing in and partnering with Teleport as part of its efforts to bring infrastructure identity everywhere, Matt Caulfield,

Read More »

DOE and SBA Launch SBIC-E Initiative to Unleash Private Capital for American Innovation and Small Businesses

WASHINGTON—The U.S. Department of Energy (DOE) and the U.S. Small Business Administration (SBA) today signed a Memorandum of Agreement establishing the Small Business Investment Company-Energy (SBIC-E) Initiative, a new strategic partnership advancing President Trump’s commitment to supporting America’s small businesses, strengthening domestic manufacturing and supply chains, and ensuring the United States leads in the technologies critical to our national and economic security. The new SBIC-E Initiative brings together DOE’s scientific and technical expertise with SBA’s proven Small Business Investment Company (SBIC) Program, which currently has $58 billion in combined portfolio value. Since 1958, the SBIC Program has invested $147 billion in American small businesses, and since 1995, SBIC-backed businesses have created or supported 10.6 million jobs. “America’s small businesses drive American innovation and affordable, reliable energy access,” said U.S. Secretary of Energy Chris Wright. “By partnering with the Small Business Administration, the Energy Department is committing to invest its resources in American small businesses that will create jobs, strengthen our domestic manufacturing base, and unleash American energy production.” Through DOE’s Office of Technology Commercialization (OTC), the Department will identify strategic technology priorities, provide technical and commercialization expertise, and help engage the investment community. SBA, through its Office of Investment and Innovation, will administer the initiative and encourage the formation and growth of investment funds focused on those priorities. SBIC-E adds another tool to that effort by connecting innovators with private capital to help promising technologies grow, scale, and build here at home. “President Trump is establishing American energy dominance, ending the Green New Scam, and putting our nations’ producers and innovators back in control at the dawn of a new era of energy reliability and abundance,” said SBA Administrator Kelly Loeffler. “Through this partnership, the SBA and Department of Energy are strengthening access to capital in the private sector to

Read More »

Energy Department Announces $500 Million Award to Revitalize American Steelmaking

WASHINGTON—The U.S. Department of Energy (DOE) today announced a $500 million award to support a $1 billion investment at Cleveland-Cliffs’ Middletown Works facility in Middletown, Ohio. Vice President JD Vance and U.S. Energy Secretary Chris Wright visited Middletown Works today to highlight the Trump Administration’s commitment to American steelworkers and the resurgence of American manufacturing. The investment will modernize American steelmaking, protect 2,300 American jobs, and strengthen the domestic steel supply chain. The project advances President Trump’s commitment to put American workers first, bring investment back to American communities, and strengthen the industries critical to America’s economic and national security. Cleveland-Cliffs determined that the business case for the original project scope no longer made sense given customers’ unwillingness to pay a “green premium” for steel. Working with DOE, Cleveland-Cliffs identified a viable alternative that will upgrade and improve the efficiency of the existing coal-fired blast furnace while also capturing and commercializing co-product blast furnace gas (BFG). “President Trump is rebuilding America’s industrial base,” said Secretary Wright. “This investment puts American workers and American manufacturing first. It will modernize one of our nation’s critical steelmaking facilities, protect thousands of jobs, and strengthen our domestic steel production—keeping Ohio at the heart of American manufacturing and strengthening our national security.” The investment will modernize critical steelmaking operations at Middletown Works by rebuilding and upgrading the plant’s main coal-fired ironmaking furnace, deploying AI to optimize furnace operations and improve energy efficiency, and building an on-site facility to convert steel mill process gases into electricity. Follow-on investments will turn industrial byproducts into materials for concrete used in regional infrastructure. “This landmark investment at Middletown Works will secure a reliable domestic supply of high-purity steel while protecting thousands of quality jobs in Ohio,” said Assistant Secretary of Energy Audrey Robertson. “DOE is proud to partner with Cleveland-Cliffs to reduce America’s dependence on foreign products

Read More »

Energy Secretary Keeps Critical Generation Available in Mid-Atlantic

WASHINGTON—U.S. Secretary of Energy Chris Wright today issued an emergency order to address critical grid reliability issues facing the Mid-Atlantic region of the United States. The emergency order directs PJM Interconnection L.L.C. (PJM), in coordination with Constellation Energy Corporation, to ensure Units 3 and 4 of the Eddystone Generating Station in Pennsylvania remain available to operate and to employ economic dispatch to minimize costs for the American people. The units were originally slated to shut down on May 31, 2025. “The energy sources that perform when you need them most are the most valuable,” Secretary Wright said. “During recent Mid-Atlantic heat waves, coal, natural gas, and nuclear kept the lights and air conditioners on. President Trump and the Energy Department are committed to keeping critical generation available when demand is highest, reducing the risk of blackouts and ensuring Americans have affordable, reliable, and secure power—regardless of whether the wind is blowing or the sun is shining.” As outlined in DOE’s Resource Adequacy Report, power outages could increase by 100 times in 2030 if the U.S. continues to take reliable power offline. This order is in effect beginning on August 23, 2026, through November 20, 2026.                                                                                             ###

Read More »

Energy Department Announces $500 Million to Secure America’s Critical Mineral and Battery Supply Chains

WASHINGTON—The U.S. Department of Energy’s (DOE) Office of Critical Minerals and Energy Innovation (CMEI) today announced $500 million for seven selected projects to expand critical mineral and material processing, battery manufacturing, and recycling capacity in the United States. In accordance with President Trump’s Executive Order, Unleashing American Energy, the selected projects advance the President’s agenda to strengthen America’s domestic critical minerals and materials supply chains, reduce reliance on foreign sources, bolster national security, and advance American energy dominance. “For too long, America has depended on foreign actors for critical materials essential to modern life that underpin our economy, energy security, and national security,” said U.S. Secretary of Energy Chris Wright. “President Trump is reversing that dependence by securing our critical supply chains, unleashing American industry, and bringing critical materials production and processing back to the United States.” “DOE is taking decisive action to secure the critical supply chains necessary to power our nation,” said Assistant Secretary of Energy Audrey Robertson. “These projects underscore DOE’s commitment to driving innovation, reducing reliance on foreign sources, and promoting American energy dominance.” This is the third round of funding from DOE’s Battery Materials Processing and Battery Manufacturing and Recycling programs, which support battery materials processing, recycling, and manufacturing projects. These include demonstration projects, construction of commercial-scale facilities, and retrofitting or retooling existing facilities.  Critical minerals and materials are essential to American industry, energy production, and national security. Expanding domestic capacity will help ensure the resources America needs are processed, manufactured, and recycled in the United States.  Information on the selected projects is available here and here.

Read More »

bp lets Shah Deniz compression automation contract

bp has let a contract to Emerson to deliver automation technologies for the Shah Deniz Compression project offshore Azerbaijan. Emerson will provide integrated control and safety systems aimed at enhancing production, safety, and reliability on the new offshore compression platform. The contract includes systems to provide process control, safety shutdown, fire and gas detection, and power management. Together, these systems deliver real-time visibility and remote control of critical operations, Emerson said. The $2.9 billion Shah Deniz Compression project, which includes an electrically powered, normally unattended offshore production platform, is a next stage development of the Caspian Sea Shah Deniz field. Designed to access low-pressure gas reserves and maximize overall recovery, the platform will be equipped with four 11 Mw compressors and serve as the central compression hub for gas from the Shah Deniz Alpha and Bravo platforms. The platform will operate remotely from bp’s onshore Sangachal terminal 55 km south of Baku. The project is expected to enable about 50 billion cu m of additional gas and about 25 million bbl of condensate production and export. Construction is scheduled to be completed in 2029, with first gas compression expected from the Shah Deniz Alpha platform in 2029 and from the Shah Deniz Bravo platform in 2030. The agreement follows a previous automation contract bp signed with Emerson for the Azeri Central East and Shah Deniz Stage 2 developments. bp is operator at Shah Deniz (29.99%) with partners Lukoil (19.99%), TPAO (19%), Cenub Qaz Dehlizi (16.02%), NICO (10%), and MVM (5%).

Read More »

Federal court voids Texas GulfLink license over agency’s ‘serious procedural errors’

The ruling voids the license, halting all construction or progress. Sentinel Midstream declined comment on the ruling and would not answer questions about the status of construction. GulfLink, sited about 30 miles offshore Freeport, Tex., is designed to export up to 1 million b/d via Very Large Crude Carriers (VLCCs) to the government of Japan and Freeport Commodities. The project involves a 44-mile, 42-in. OD pipeline and was scheduled to begin operations around 2028. The estimated $2.1 billion investment was funded as part of a broader trade agreement between the US and Japan. The legal battle stems from a specific rule in the Deepwater Port Act of 1974 that dictates that the federal government can only permit one crude oil deepwater port, including any supporting infrastructure, within a single designated “application area.” Because the competing SPOT project’s pipeline route physically overlaps and intersects GulfLink’s lines, the plaintiff—Citizens for Clean Air & Clean Water in Brazoria County (Better Brazoria), represented by Earthjustice—successfully argued that MARAD violated the “one port” rule when issuing GulfLink’s license in February. The three-judge panel found that MARAD “improperly drew” the map designing the project’s official boundaries to exclude the pipelines and approved two overlapping projects in the same zone instead of only licensing one. The court wrote that the scope of the error made vacatur, not the less serious remand without vacatur, the appropriate remedy. Vacatur deems the license invalid and is used when the court finds “serious procedural errors” that cannot be easily explained or fixed with minor changes. Remand without vacatur sends the decision back to the agency for corrections but leaves the current license in place in the meantime. SPOT project status The $2.5-3-billion SPOT project, developed by Enterprise Products Partners in partnership with Enbridge Inc., also lies about 30 miles from Freeport. Designed to handle VLCCs,

Read More »

IBM unveils dual-architecture processor to run Arm-native apps on Z mainframes

“These caches have enormously low latency, and that is one of the key reasons and key engineering choices to support the performance and scalability of enterprise workloads, very data-intensive workloads like databases and transactions,” Jacobi said. “In addition, we have an on-chip data processing unit for IO acceleration and dedicated AI accelerators as well as accelerators for data compression, cryptography and data sorting.” One of the biggest takeaways from this processor announcement is that the enormous catalog of software already built for Arm becomes accessible on a mainframe without anyone having to port it first, notes Matt Kimball, senior datacenter analyst at Moor Insights & Strategy, in a research note about the news. Still, “this is a 2027 conversation, and with no date, supported software list, or Arm licensing treatment, the work now is inventory and scenario planning rather than financial modeling,” Kimball wrote.

Read More »

PJM’s New Data Center Power Equation

PJM Interconnection has now filed one of the most consequential proposed changes yet in the relationship between data centers and the electric grid. Rather than simply treating a new hyperscale or AI facility like any other customer whose demand will be backed through regional capacity procurement, PJM is proposing a framework under which the largest new loads would need to be supported by new capacity, have their needs covered through the Reliability Backstop Procurement, or face potential curtailment when the regional power system is short of supply. The approach has been developing since PJM launched its Critical Issue Fast Path process for large loads in 2025, but it became substantially more concrete in late July and August 2026. PJM filed its proposed Reliability Backstop Procurement with FERC on July 31 and began accepting applications that day for its FERC-approved Expedited Interconnection Track. On Aug. 13, PJM filed its proposed Interim Resource Adequacy Service, or IRAS, along with the Large Load Registry that would support it. The immediate numbers explain the urgency. PJM’s July 2026 capacity auction for the 2028/2029 delivery year procured 138,318 MW of unforced capacity through the centralized auction. Even after including Fixed Resource Requirement resources, however, PJM came up 6,831 MW short of its reliability requirement. The auction cleared at the FERC-approved $325/MW-day price cap. It was the second consecutive auction in which the PJM region failed to procure its full reliability requirement, something that had not happened before these two auctions. That gap is occurring while demand continues to accelerate. PJM’s 2026 long-term forecast projects summer peak demand growing at an average 3.6% annually over the next decade, compared with just 0.3% in the comparable forecast issued in 2021. Summer peak demand is projected to rise by nearly 66 GW over 10 years. Data centers are

Read More »

Zayo, NVIDIA Build the Long-Haul Backbone for Distributed AI

The data center industry’s increasingly power-first approach to site selection has created a follow-on question: Once the megawatts are found, is there enough network infrastructure to make the site useful at AI scale? Zayo and NVIDIA are putting real infrastructure behind that question. Zayo said it is working with NVIDIA to expand network capacity supporting AI factories across North America, including an 8,000-route-mile program targeting some of the fastest-growing AI corridors in the United States. The project encompasses six new long-haul routes along with overbuilds of existing network across 10 high-demand corridors. The announcement arrives as AI data center development moves beyond the largest established hubs toward markets where power and land may be more readily available, but fiber capacity cannot necessarily be taken for granted. That geography is increasingly important. NVIDIA has separately developed “scale-across” networking technology designed to allow AI infrastructure distributed among different buildings — or even data centers separated by hundreds of kilometers — to operate as a more unified computing environment. Put together, the developments suggest that networking is becoming inseparable from the AI factory buildout itself. Power may determine where the next generation of AI infrastructure can be built. Fiber will increasingly determine how effectively those sites can participate in the larger AI ecosystem. Fiber Follows the Power Zayo CEO Steve Smith said AI demand is changing both where network infrastructure is needed and how aggressively capacity must be deployed ahead of development. “AI is fundamentally reshaping where and how network infrastructure needs to be built across the U.S.,” Smith said. The company’s 8,000-mile program is more nuanced than that top-line number might suggest. Zayo disclosed in April that the expansion includes approximately 3,000 route miles across six new long-haul routes, plus more than 5,000 route miles of overbuilds across 10 existing corridors. Zayo

Read More »

Southern’s 17 GW Pipeline Puts AI Power Demand Into Utility Math

The headline number from Southern Company’s latest earnings report is hard to miss: electricity use by data centers across the utility’s system increased 55% in the second quarter compared with a year earlier. But the more consequential numbers may be the ones sitting behind it. Southern now has more than 1.2 GW of operating data center load, up by more than 500 MW from a year ago. At the same time, its electric utilities have signed contracts and large-load agreements totaling more than 17 GW by the mid-2030s, with another 8 GW in late-stage development and a prospective pipeline of large industrial and data center projects exceeding 75 GW. That leaves an enormous gap between the data center megawatts consuming electricity today and the load Southern has contractually positioned itself to serve during the next decade. For the data center industry, that gap may be the most important part of Southern’s second-quarter story. It offers a look at how utilities are beginning to convert the AI infrastructure boom from forecasts and campus announcements into contracts, generation procurement, transmission investment and eventually energized capacity. From Contracts to Megawatts Southern added roughly 6 GW of contracted large load during the quarter alone. Alabama Power signed three projects representing about 3 GW, while Georgia Power reached a 25-year agreement to serve OpenAI’s planned project in Effingham County near Savannah. That facility is expected to require approximately 3.2 GW and begin taking electric service in phases in 2028. The numbers nevertheless require an important distinction. Seventeen gigawatts contracted does not mean 17 GW will suddenly appear on Southern’s grid. Large data center campuses ramp gradually, often over several years, and Southern executives acknowledged that actual customer ramp schedules do not always match the assumptions made when projects are first approved. CEO Chris Womack said

Read More »

PORTS-Pike Takes Shape as an 8-GW AI Infrastructure Model

Back on March 31, 2026, we discussed we discussed SoftBank and SB Energy’s plans to redevelop the former Portsmouth Gaseous Diffusion Plant site near Piketon as a 10-GW artificial intelligence data center campus supported by almost an equal amount of new power generation. At the time, the plan called for as much as 10 GW of new generation, including 9.2 GW of natural gas capacity, along with approximately $4.2 billion of high-voltage transmission infrastructure developed with AEP Ohio. An initial 800-MW data center phase was targeted for service in 2028. The March story was notable because Pike County appeared to offer a preview of a new model for building hyperscale infrastructure: develop the generation, transmission and data center simultaneously rather than wait for an increasingly congested regional grid to deliver multiple gigawatts of capacity. Not to mention the reuse of a brownfield site with the encouragement of the federal government. Since then, almost every important part of the project has moved forward, and on August 17, the most consequential missing pieces fell into place. NVIDIA announced that it will become the exclusive AI compute infrastructure provider for the PORTS-Pike Technology Campus. OpenAI will be the data center customer, signing a 20-year lease with SB Energy for approximately 8 GW of IT capacity. NVIDIA will invest another $1.5 billion in SB Energy and provide credit support for the land, power and shell infrastructure behind an initial 4.25 GW of IT load, with an option covering approximately another 3.75 GW. The Securities and Exchange Commission filing accompanying the announcement makes the financial commitment even more significant. NVIDIA disclosed that its aggregate payment obligation associated with its initial commitment is capped at $105 billion. That is not a conventional capital commitment to spend $105 billion building the campus, nor is it simply a

Read More »

Nvidia scales back financing guarantee for OpenAI data center

Nvidia is scaling back a proposed financial guarantee tied to a massive OpenAI data center project in Ohio, reducing its initial commitment from as much as $250 billion to less than $120 billion, according to report in the Wall Street Journal. Earlier this month, Nvidia announced partnerships with major financial firms including Apollo Global Management, BlackRock, Blackstone, Brookfield Asset Management, Goldman Sachs and KKR, aimed at mobilizing more than $500 billion in capital for AI computing infrastructure. The change represents a significant restructuring of Nvidia’s role in financing the planned facility, which is being developed by SB Energy, a subsidiary of SoftBank. Under the revised arrangement, Nvidia would guarantee financing for the project’s first phase, representing roughly 5 gigawatts of capacity, or half of the total proposed capacity. Financing for the remaining capacity would be considered separately at a later stage.

Read More »

Microsoft will invest $80B in AI data centers in fiscal 2025

And Microsoft isn’t the only one that is ramping up its investments into AI-enabled data centers. Rival cloud service providers are all investing in either upgrading or opening new data centers to capture a larger chunk of business from developers and users of large language models (LLMs).  In a report published in October 2024, Bloomberg Intelligence estimated that demand for generative AI would push Microsoft, AWS, Google, Oracle, Meta, and Apple would between them devote $200 billion to capex in 2025, up from $110 billion in 2023. Microsoft is one of the biggest spenders, followed closely by Google and AWS, Bloomberg Intelligence said. Its estimate of Microsoft’s capital spending on AI, at $62.4 billion for calendar 2025, is lower than Smith’s claim that the company will invest $80 billion in the fiscal year to June 30, 2025. Both figures, though, are way higher than Microsoft’s 2020 capital expenditure of “just” $17.6 billion. The majority of the increased spending is tied to cloud services and the expansion of AI infrastructure needed to provide compute capacity for OpenAI workloads. Separately, last October Amazon CEO Andy Jassy said his company planned total capex spend of $75 billion in 2024 and even more in 2025, with much of it going to AWS, its cloud computing division.

Read More »

John Deere unveils more autonomous farm machines to address skill labor shortage

Join our daily and weekly newsletters for the latest updates and exclusive content on industry-leading AI coverage. Learn More Self-driving tractors might be the path to self-driving cars. John Deere has revealed a new line of autonomous machines and tech across agriculture, construction and commercial landscaping. The Moline, Illinois-based John Deere has been in business for 187 years, yet it’s been a regular as a non-tech company showing off technology at the big tech trade show in Las Vegas and is back at CES 2025 with more autonomous tractors and other vehicles. This is not something we usually cover, but John Deere has a lot of data that is interesting in the big picture of tech. The message from the company is that there aren’t enough skilled farm laborers to do the work that its customers need. It’s been a challenge for most of the last two decades, said Jahmy Hindman, CTO at John Deere, in a briefing. Much of the tech will come this fall and after that. He noted that the average farmer in the U.S. is over 58 and works 12 to 18 hours a day to grow food for us. And he said the American Farm Bureau Federation estimates there are roughly 2.4 million farm jobs that need to be filled annually; and the agricultural work force continues to shrink. (This is my hint to the anti-immigration crowd). John Deere’s autonomous 9RX Tractor. Farmers can oversee it using an app. While each of these industries experiences their own set of challenges, a commonality across all is skilled labor availability. In construction, about 80% percent of contractors struggle to find skilled labor. And in commercial landscaping, 86% of landscaping business owners can’t find labor to fill open positions, he said. “They have to figure out how to do

Read More »

2025 playbook for enterprise AI success, from agents to evals

Join our daily and weekly newsletters for the latest updates and exclusive content on industry-leading AI coverage. Learn More 2025 is poised to be a pivotal year for enterprise AI. The past year has seen rapid innovation, and this year will see the same. This has made it more critical than ever to revisit your AI strategy to stay competitive and create value for your customers. From scaling AI agents to optimizing costs, here are the five critical areas enterprises should prioritize for their AI strategy this year. 1. Agents: the next generation of automation AI agents are no longer theoretical. In 2025, they’re indispensable tools for enterprises looking to streamline operations and enhance customer interactions. Unlike traditional software, agents powered by large language models (LLMs) can make nuanced decisions, navigate complex multi-step tasks, and integrate seamlessly with tools and APIs. At the start of 2024, agents were not ready for prime time, making frustrating mistakes like hallucinating URLs. They started getting better as frontier large language models themselves improved. “Let me put it this way,” said Sam Witteveen, cofounder of Red Dragon, a company that develops agents for companies, and that recently reviewed the 48 agents it built last year. “Interestingly, the ones that we built at the start of the year, a lot of those worked way better at the end of the year just because the models got better.” Witteveen shared this in the video podcast we filmed to discuss these five big trends in detail. Models are getting better and hallucinating less, and they’re also being trained to do agentic tasks. Another feature that the model providers are researching is a way to use the LLM as a judge, and as models get cheaper (something we’ll cover below), companies can use three or more models to

Read More »

OpenAI’s red teaming innovations define new essentials for security leaders in the AI era

Join our daily and weekly newsletters for the latest updates and exclusive content on industry-leading AI coverage. Learn More OpenAI has taken a more aggressive approach to red teaming than its AI competitors, demonstrating its security teams’ advanced capabilities in two areas: multi-step reinforcement and external red teaming. OpenAI recently released two papers that set a new competitive standard for improving the quality, reliability and safety of AI models in these two techniques and more. The first paper, “OpenAI’s Approach to External Red Teaming for AI Models and Systems,” reports that specialized teams outside the company have proven effective in uncovering vulnerabilities that might otherwise have made it into a released model because in-house testing techniques may have missed them. In the second paper, “Diverse and Effective Red Teaming with Auto-Generated Rewards and Multi-Step Reinforcement Learning,” OpenAI introduces an automated framework that relies on iterative reinforcement learning to generate a broad spectrum of novel, wide-ranging attacks. Going all-in on red teaming pays practical, competitive dividends It’s encouraging to see competitive intensity in red teaming growing among AI companies. When Anthropic released its AI red team guidelines in June of last year, it joined AI providers including Google, Microsoft, Nvidia, OpenAI, and even the U.S.’s National Institute of Standards and Technology (NIST), which all had released red teaming frameworks. Investing heavily in red teaming yields tangible benefits for security leaders in any organization. OpenAI’s paper on external red teaming provides a detailed analysis of how the company strives to create specialized external teams that include cybersecurity and subject matter experts. The goal is to see if knowledgeable external teams can defeat models’ security perimeters and find gaps in their security, biases and controls that prompt-based testing couldn’t find. What makes OpenAI’s recent papers noteworthy is how well they define using human-in-the-middle

Read More »