Skip to content

Commit 64ec8fc

Browse files
committed
feat: add max query row count to mitigate LLM abuse
1 parent 3350cda commit 64ec8fc

File tree

3 files changed

+20
-4
lines changed

3 files changed

+20
-4
lines changed

apps/postgres-new/app/api/chat/route.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { openai } from '@ai-sdk/openai'
22
import { ToolInvocation, convertToCoreMessages, streamText } from 'ai'
33
import { codeBlock } from 'common-tags'
4-
import { convertToCoreTools, tools } from '~/lib/tools'
4+
import { convertToCoreTools, maxRowLimit, tools } from '~/lib/tools'
55

66
// Allow streaming responses up to 30 seconds
77
export const maxDuration = 30
@@ -39,7 +39,8 @@ export async function POST(req: Request) {
3939
- Make the data realistic, including joined data
4040
- Check for existing records/conflicts in the table
4141
42-
When querying data, limit to 5 by default.
42+
When querying data, limit to 5 by default. The maximum number of rows you're allowed to fetch is ${maxRowLimit} (to protect AI from token abuse).
43+
If the user needs to fetch more than ${maxRowLimit} rows at once, they can export the query as a CSV.
4344
4445
When performing FTS, always use 'simple' (languages aren't available).
4546

apps/postgres-new/lib/hooks.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import { useTablesQuery } from '~/data/tables/tables-query'
2020
import { embed } from './embed'
2121
import { loadFile, saveFile } from './files'
2222
import { SmoothScroller } from './smooth-scroller'
23-
import { OnToolCall } from './tools'
23+
import { maxRowLimit, OnToolCall } from './tools'
2424

2525
export function useDebounce<T>(value: T, delay: number) {
2626
const [debouncedValue, setDebouncedValue] = useState(value)
@@ -265,7 +265,17 @@ export function useOnToolCall(databaseId: string) {
265265

266266
const results = await db.exec(sql)
267267

268-
// Truncate vector columns due to their large size
268+
const oversizedResult = results.find((result) => result.rows.length > maxRowLimit)
269+
270+
// We have a max row count in place to mitigate LLM token abuse
271+
if (oversizedResult) {
272+
return {
273+
success: false,
274+
error: `Query produced ${oversizedResult.rows.length} rows but the max allowed limit is ${maxRowLimit}. Rerun the query with a limit of ${maxRowLimit}.`,
275+
}
276+
}
277+
278+
// Truncate vector columns due to their large size (display purposes only)
269279
const filteredResults = results.map((result) => {
270280
const vectorFields = result.fields.filter(
271281
(field) => field.dataTypeID === vectorDataTypeId

apps/postgres-new/lib/tools.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@ function result<T extends z.ZodTypeAny>(schema: T) {
1616
return z.union([z.intersection(successResultSchema, schema), errorResultSchema])
1717
}
1818

19+
/**
20+
* The maximum SQL result row limit to prevent overloading LLM.
21+
*/
22+
export const maxRowLimit = 100
23+
1924
/**
2025
* Central location for all LLM tools including their
2126
* description, arg schema, and result schema.

0 commit comments

Comments
 (0)