Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add better error message when the tableinfo method return too much info #662

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 36 additions & 1 deletion langchain/src/chains/sql_db/sql_db_chain.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
import type { TiktokenModel } from "@dqbd/tiktoken";
import { DEFAULT_SQL_DATABASE_PROMPT } from "./sql_db_prompt.js";
import { BaseChain } from "../base.js";
import type { OpenAI } from "../../llms/openai.js";
import { BaseMemory } from "../../memory/base.js";
import { LLMChain } from "../llm_chain.js";
import type { SqlDatabase } from "../../sql_db.js";
import { ChainValues } from "../../schema/index.js";
import { SerializedSqlDatabaseChain } from "../serde.js";
import { BaseLanguageModel } from "../../base_language/index.js";
import {
calculateMaxTokens,
getModelContextSize,
} from "../../base_language/count_tokens.js";

export class SqlDatabaseChain extends BaseChain {
// LLM wrapper to use
Expand Down Expand Up @@ -64,8 +70,9 @@ export class SqlDatabaseChain extends BaseChain {
table_info: tableInfo,
stop: ["\nSQLResult:"],
};
await this.verifyNumberOfTokens(inputText, tableInfo);

const intermediateStep = [];
const intermediateStep: string[] = [];
const sqlCommand = await lLMChain.predict(llmInputs);
intermediateStep.push(sqlCommand);
let queryResult = "";
Expand Down Expand Up @@ -118,4 +125,32 @@ export class SqlDatabaseChain extends BaseChain {
sql_database: this.database.serialize(),
};
}

private async verifyNumberOfTokens(
inputText: string,
tableinfo: string
): Promise<void> {
// We verify it only for OpenAI for the moment
if (this.llm._modelType() !== "openai") {
return;
}
const llm = this.llm as OpenAI;
const promptTemplate = this.prompt.template;
const stringWeSend = `${inputText}${promptTemplate}${tableinfo}`;
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's an easy to understand approximation of the final string


const maxToken = await calculateMaxTokens({
prompt: stringWeSend,
// Cast here to allow for other models that may not fit the union
modelName: llm.modelName as TiktokenModel,
});

if (maxToken < llm.maxTokens) {
throw new Error(`The combination of the database structure and your question is too big for the model ${
llm.modelName
} which can compute only a max tokens of ${getModelContextSize(
llm.modelName
)}.
We suggest you to use the includeTables parameters when creating the SqlDatabase object to select only a subset of the tables. You can also use a model which can handle more tokens.`);
}
}
}
65 changes: 64 additions & 1 deletion langchain/src/chains/tests/sql_db_chain.int.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { test } from "@jest/globals";
import { expect, test } from "@jest/globals";
import { DataSource } from "typeorm";
import { OpenAI } from "../../llms/openai.js";
import { SqlDatabaseChain } from "../sql_db/sql_db_chain.js";
Expand Down Expand Up @@ -39,3 +39,66 @@ test("Test SqlDatabaseChain", async () => {

await datasource.destroy();
});

// We create this string to reach the token limit of the query built to describe the database and get the SQL query.
const veryLongString = `Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam orci nisi, vulputate ac pulvinar eu, maximus a tortor. Duis suscipit, nibh vel fermentum vehicula, mauris ante convallis metus, et feugiat turpis mauris non felis. Interdum et malesuada fames ac ante ipsum primis in faucibus. Maecenas efficitur nibh in nisi sagittis ultrices. Donec id velit nunc. Nam a lacus risus. Vestibulum molestie massa eget convallis pellentesque.
Mauris a nisl eget velit finibus blandit ac a odio. Sed sagittis consequat urna a egestas. Curabitur pretium convallis nibh, in ullamcorper odio tempus nec. Curabitur laoreet nec nisl sed accumsan. Sed elementum eleifend molestie. Aenean ullamcorper interdum risus, eget pharetra est volutpat ut. Aenean maximus consequat justo rutrum finibus. Mauris consequat facilisis consectetur. Vivamus rutrum dignissim libero, non aliquam lectus tempus id. In hac habitasse platea dictumst. Sed at magna dignissim, tincidunt lectus in, malesuada risus. Phasellus placerat blandit ligula. Integer posuere id elit at commodo. Sed consequat sagittis odio eget congue.
Aliquam ultricies, sapien a porta luctus, dolor nibh dignissim erat, dictum luctus orci lorem non quam. Quisque dapibus tempus mattis. Suspendisse gravida consequat mi at viverra. Quisque sed est purus. Fusce tincidunt semper massa eu blandit. Donec in lacus a tortor facilisis facilisis. Interdum et malesuada fames ac ante ipsum primis in faucibus. In aliquam dignissim eros ac consectetur. Aliquam fringilla magna erat. Nullam tincidunt maximus nulla, quis gravida est varius vel. Aliquam cursus, diam non facilisis mollis, nunc diam convallis enim, ac tempus diam tortor in dui. Nunc feugiat ligula odio, eleifend fermentum quam tincidunt sed. Duis pellentesque quam eget volutpat commodo.
Aliquam ex velit, porta sit amet augue vulputate, rhoncus fermentum magna. Integer non elementum augue. Phasellus rhoncus nisl nec magna lacinia vulputate. Suspendisse diam nibh, egestas a porta a, pellentesque ut nisl. Donec tempus ligula at leo convallis consequat. Duis sapien lorem, lobortis ac nisl dapibus, bibendum mollis lorem. Sed congue porttitor ex, eget scelerisque ligula consectetur quis. Mauris felis mauris, sodales quis nunc non, condimentum eleifend quam. Ut vitae viverra lorem. Vivamus lacinia et dolor vitae cursus. Proin faucibus venenatis enim vitae tincidunt. Sed sed venenatis leo.
Donec eu erat ullamcorper, consectetur dui sed, cursus tellus. Phasellus consectetur felis augue, quis auctor odio semper ac. In scelerisque gravida ligula eget lobortis. Sed tristique ultricies fringilla. Nunc in ultrices purus. Curabitur dictum cursus ante, at tempus est interdum at. Donec gravida lectus ut purus vestibulum, eu accumsan nisl pharetra.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam orci nisi, vulputate ac pulvinar eu, maximus a tortor. Duis suscipit, nibh vel fermentum vehicula, mauris ante convallis metus, et feugiat turpis mauris non felis. Interdum et malesuada fames ac ante ipsum primis in faucibus. Maecenas efficitur nibh in nisi sagittis ultrices. Donec id velit nunc. Nam a lacus risus. Vestibulum molestie massa eget convallis pellentesque.
Mauris a nisl eget velit finibus blandit ac a odio. Sed sagittis consequat urna a egestas. Curabitur pretium convallis nibh, in ullamcorper odio tempus nec. Curabitur laoreet nec nisl sed accumsan. Sed elementum eleifend molestie. Aenean ullamcorper interdum risus, eget pharetra est volutpat ut. Aenean maximus consequat justo rutrum finibus. Mauris consequat facilisis consectetur. Vivamus rutrum dignissim libero, non aliquam lectus tempus id. In hac habitasse platea dictumst. Sed at magna dignissim, tincidunt lectus in, malesuada risus. Phasellus placerat blandit ligula. Integer posuere id elit at commodo. Sed consequat sagittis odio eget congue.
Aliquam ultricies, sapien a porta luctus, dolor nibh dignissim erat, dictum luctus orci lorem non quam. Quisque dapibus tempus mattis. Suspendisse gravida consequat mi at viverra. Quisque sed est purus. Fusce tincidunt semper massa eu blandit. Donec in lacus a tortor facilisis facilisis. Interdum et malesuada fames ac ante ipsum primis in faucibus. In aliquam dignissim eros ac consectetur. Aliquam fringilla magna erat. Nullam tincidunt maximus nulla, quis gravida est varius vel. Aliquam cursus, diam non facilisis mollis, nunc diam convallis enim, ac tempus diam tortor in dui. Nunc feugiat ligula odio, eleifend fermentum quam tincidunt sed. Duis pellentesque quam eget volutpat commodo.
Aliquam ex velit, porta sit amet augue vulputate, rhoncus fermentum magna. Integer non elementum augue. Phasellus rhoncus nisl nec magna lacinia vulputate. Suspendisse diam nibh, egestas a porta a, pellentesque ut nisl. Donec tempus ligula at leo convallis consequat. Duis sapien lorem, lobortis ac nisl dapibus, bibendum mollis lorem. Sed congue porttitor ex, eget scelerisque ligula consectetur quis. Mauris felis mauris, sodales quis nunc non, condimentum eleifend quam. Ut vitae viverra lorem. Vivamus lacinia et dolor vitae cursus. Proin faucibus venenatis enim vitae tincidunt. Sed sed venenatis leo.
Donec eu erat ullamcorper, consectetur dui sed, cursus tellus. Phasellus consectetur felis augue, quis auctor odio semper ac. In scelerisque gravida ligula eget lobortis. Sed tristique ultricies fringilla. Nunc in ultrices purus. Curabitur dictum cursus ante, at tempus est interdum at. Donec gravida lectus ut purus vestibulum, eu accumsan nisl pharetra.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam orci nisi, vulputate ac pulvinar eu, maximus a tortor. Duis suscipit, nibh vel fermentum vehicula, mauris ante convallis metus, et feugiat turpis mauris non felis. Interdum et malesuada fames ac ante ipsum primis in faucibus. Maecenas efficitur nibh in nisi sagittis ultrices. Donec id velit nunc. Nam a lacus risus. Vestibulum molestie massa eget convallis pellentesque.
Mauris a nisl eget velit finibus blandit ac a odio. Sed sagittis consequat urna a egestas. Curabitur pretium convallis nibh, in ullamcorper odio tempus nec. Curabitur laoreet nec nisl sed accumsan. Sed elementum eleifend molestie. Aenean ullamcorper interdum risus, eget pharetra est volutpat ut. Aenean maximus consequat justo rutrum finibus. Mauris consequat facilisis consectetur. Vivamus rutrum dignissim libero, non aliquam lectus tempus id. In hac habitasse platea dictumst. Sed at magna dignissim, tincidunt lectus in, malesuada risus. Phasellus placerat blandit ligula. Integer posuere id elit at commodo. Sed consequat sagittis odio eget congue.
Aliquam ultricies, sapien a porta luctus, dolor nibh dignissim erat, dictum luctus orci lorem non quam. Quisque dapibus tempus mattis. Suspendisse gravida consequat mi at viverra. Quisque sed est purus. Fusce tincidunt semper massa eu blandit. Donec in lacus a tortor facilisis facilisis. Interdum et malesuada fames ac ante ipsum primis in faucibus. In aliquam dignissim eros ac consectetur. Aliquam fringilla magna erat. Nullam tincidunt maximus nulla, quis gravida est varius vel. Aliquam cursus, diam non facilisis mollis, nunc diam convallis enim, ac tempus diam tortor in dui. Nunc feugiat ligula odio, eleifend fermentum quam tincidunt sed. Duis pellentesque quam eget volutpat commodo.
Aliquam ex velit, porta sit amet augue vulputate, rhoncus fermentum magna. Integer non elementum augue. Phasellus rhoncus nisl nec magna lacinia vulputate. Suspendisse diam nibh, egestas a porta a, pellentesque ut nisl. Donec tempus ligula at leo convallis consequat. Duis sapien lorem, lobortis ac nisl dapibus, bibendum mollis lorem. Sed congue porttitor ex, eget scelerisque ligula consectetur quis. Mauris felis mauris, sodales quis nunc non, condimentum eleifend quam. Ut vitae viverra lorem. Vivamus lacinia et dolor vitae cursus. Proin faucibus venenatis enim vitae tincidunt. Sed sed venenatis leo.
Donec eu erat ullamcorper, consectetur dui sed, cursus tellus. Phasellus consectetur felis augue, quis auctor odio semper ac. In scelerisque gravida ligula eget lobortis. Sed tristique ultricies fringilla. Nunc in ultrices purus. Curabitur dictum cursus ante, at tempus est interdum at. Donec gravida lectus ut purus vestibulum, eu accumsan nisl pharetra.
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam orci nisi, vulputate ac pulvinar eu, maximus a tortor. Duis suscipit, nibh vel fermentum vehicula, mauris ante convallis metus, et feugiat turpis mauris non felis. Interdum et malesuada fames ac ante ipsum primis in faucibus. Maecenas efficitur nibh in nisi sagittis ultrices. Donec id velit nunc. Nam a lacus risus. Vestibulum molestie massa eget convallis pellentesque.
Mauris a nisl eget velit finibus blandit ac a odio. Sed sagittis consequat urna a egestas. Curabitur pretium convallis nibh, in ullamcorper odio tempus nec. Curabitur laoreet nec nisl sed accumsan. Sed elementum eleifend molestie. Aenean ullamcorper interdum risus, eget pharetra est volutpat ut. Aenean maximus consequat justo rutrum finibus. Mauris consequat facilisis consectetur. Vivamus rutrum dignissim libero, non aliquam lectus tempus id. In hac habitasse platea dictumst. Sed at magna dignissim, tincidunt lectus in, malesuada risus. Phasellus placerat blandit ligula. Integer posuere id elit at commodo. Sed consequat sagittis odio eget congue.
Aliquam ultricies, sapien a porta luctus, dolor nibh dignissim erat, dictum luctus orci lorem non quam. Quisque dapibus tempus mattis. Suspendisse gravida consequat mi at viverra. Quisque sed est purus. Fusce tincidunt semper massa eu blandit. Donec in lacus a tortor facilisis facilisis. Interdum et malesuada fames ac ante ipsum primis in faucibus. In aliquam dignissim eros ac consectetur. Aliquam fringilla magna erat. Nullam tincidunt maximus nulla, quis gravida est varius vel. Aliquam cursus, diam non facilisis mollis, nunc diam convallis enim, ac tempus diam tortor in dui. Nunc feugiat ligula odio, eleifend fermentum quam tincidunt sed. Duis pellentesque quam eget volutpat commodo.
Aliquam ex velit, porta sit amet augue vulputate, rhoncus fermentum magna. Integer non elementum augue. Phasellus rhoncus nisl nec magna lacinia vulputate. Suspendisse diam nibh, egestas a porta a, pellentesque ut nisl. Donec tempus ligula at leo convallis consequat. Duis sapien lorem, lobortis ac nisl dapibus, bibendum mollis lorem. Sed congue porttitor ex, eget scelerisque ligula consectetur quis. Mauris felis mauris, sodales quis nunc non, condimentum eleifend quam. Ut vitae viverra lorem. Vivamus lacinia et dolor vitae cursus. Proin faucibus venenatis enim vitae tincidunt. Sed sed venenatis leo.
`;

test("Test token limite SqlDatabaseChain", async () => {
const datasource = new DataSource({
type: "sqlite",
database: ":memory:",
synchronize: true,
});

await datasource.initialize();
await datasource.query(`
CREATE TABLE users (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, age INTEGER);
`);
await datasource.query(`
INSERT INTO users (name, age) VALUES ('Alice', 20);
`);
await datasource.query(`
INSERT INTO users (name, age) VALUES ('Bob', 21);
`);

// eslint-disable-next-line @typescript-eslint/no-use-before-define
await datasource.query(`
INSERT INTO users (name, age) VALUES ('${veryLongString}', 22);
`);

const db = await SqlDatabase.fromDataSourceParams({
appDataSource: datasource,
});

const chain = new SqlDatabaseChain({
llm: new OpenAI({ temperature: 0 }),
database: db,
});

const runChain = async () => {
await chain.run("How many users are there?");
};

await expect(runChain()).rejects.toThrow();

await datasource.destroy();
});