new(whatsapp.gblib): LLM SQL.
This commit is contained in:
parent
9c53ae24bc
commit
e090b62246
2 changed files with 79 additions and 14 deletions
|
@ -192,6 +192,7 @@
|
||||||
"rimraf": "5.0.7",
|
"rimraf": "5.0.7",
|
||||||
"safe-buffer": "5.2.1",
|
"safe-buffer": "5.2.1",
|
||||||
"scanf": "1.2.0",
|
"scanf": "1.2.0",
|
||||||
|
"sqlite3": "5.1.7",
|
||||||
"sequelize": "6.28.2",
|
"sequelize": "6.28.2",
|
||||||
"sequelize-cli": "6.6.0",
|
"sequelize-cli": "6.6.0",
|
||||||
"sequelize-typescript": "2.1.5",
|
"sequelize-typescript": "2.1.5",
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
\*****************************************************************************/
|
\*****************************************************************************/
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
import { PromptTemplate } from '@langchain/core/prompts';
|
||||||
import { WikipediaQueryRun } from '@langchain/community/tools/wikipedia_query_run';
|
import { WikipediaQueryRun } from '@langchain/community/tools/wikipedia_query_run';
|
||||||
import { HNSWLib } from '@langchain/community/vectorstores/hnswlib';
|
import { HNSWLib } from '@langchain/community/vectorstores/hnswlib';
|
||||||
import { BaseCallbackHandler } from '@langchain/core/callbacks/base';
|
import { BaseCallbackHandler } from '@langchain/core/callbacks/base';
|
||||||
|
@ -48,7 +48,7 @@ import { convertToOpenAITool } from '@langchain/core/utils/function_calling';
|
||||||
import { ChatOpenAI, OpenAI } from '@langchain/openai';
|
import { ChatOpenAI, OpenAI } from '@langchain/openai';
|
||||||
import { SqlDatabaseChain } from 'langchain/chains/sql_db';
|
import { SqlDatabaseChain } from 'langchain/chains/sql_db';
|
||||||
import { SqlDatabase } from 'langchain/sql_db';
|
import { SqlDatabase } from 'langchain/sql_db';
|
||||||
import {DataSource } from 'typeorm';
|
import { DataSource } from 'typeorm';
|
||||||
import { GBMinInstance } from 'botlib';
|
import { GBMinInstance } from 'botlib';
|
||||||
import * as Fs from 'fs';
|
import * as Fs from 'fs';
|
||||||
import { jsonSchemaToZod } from 'json-schema-to-zod';
|
import { jsonSchemaToZod } from 'json-schema-to-zod';
|
||||||
|
@ -477,13 +477,11 @@ export class ChatServices {
|
||||||
// const username = con['storageUsername'];
|
// const username = con['storageUsername'];
|
||||||
// const password = con['storagePassword'];
|
// const password = con['storagePassword'];
|
||||||
|
|
||||||
|
|
||||||
const dataSource = new DataSource({
|
const dataSource = new DataSource({
|
||||||
type: 'sqlite',
|
type: 'sqlite',
|
||||||
database: "/home/gbadmin3910/DATA/BotServer/work/frukigbot1.gbai/data.db",
|
database: '/home/gbadmin3910/DATA/BotServer/work/frukigbot1.gbai/data.db'
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
// const dataSource = new DataSource({
|
// const dataSource = new DataSource({
|
||||||
// type: dialect as any,
|
// type: dialect as any,
|
||||||
// host: host,
|
// host: host,
|
||||||
|
@ -499,12 +497,78 @@ export class ChatServices {
|
||||||
appDataSource: dataSource
|
appDataSource: dataSource
|
||||||
});
|
});
|
||||||
|
|
||||||
const chain = new SqlDatabaseChain({
|
const prompt =
|
||||||
llm: model,
|
PromptTemplate.fromTemplate(`Based on the provided SQL table schema below, write a SQL query that would answer the user's question.
|
||||||
database: db,
|
------------
|
||||||
|
SCHEMA: {schema}
|
||||||
|
------------
|
||||||
|
QUESTION: {question}
|
||||||
|
------------
|
||||||
|
SQL QUERY:`);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new RunnableSequence where we pipe the output from `db.getTableInfo()`
|
||||||
|
* and the users question, into the prompt template, and then into the llm.
|
||||||
|
* We're also applying a stop condition to the llm, so that it stops when it
|
||||||
|
* sees the `\nSQLResult:` token.
|
||||||
|
*/
|
||||||
|
const sqlQueryChain = RunnableSequence.from([
|
||||||
|
{
|
||||||
|
schema: async () => db.getTableInfo(),
|
||||||
|
question: (input: { question: string }) => input.question
|
||||||
|
},
|
||||||
|
prompt,
|
||||||
|
model.bind({ stop: ['\nSQLResult:'] }),
|
||||||
|
new StringOutputParser()
|
||||||
|
]);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create the final prompt template which is tasked with getting the natural
|
||||||
|
* language response to the SQL query.
|
||||||
|
*/
|
||||||
|
const finalResponsePrompt =
|
||||||
|
PromptTemplate.fromTemplate(`Based on the table schema below, question, SQL query, and SQL response, write a natural language response:
|
||||||
|
------------
|
||||||
|
SCHEMA: {schema}
|
||||||
|
------------
|
||||||
|
QUESTION: {question}
|
||||||
|
------------
|
||||||
|
SQL QUERY: {query}
|
||||||
|
------------
|
||||||
|
SQL RESPONSE: {response}
|
||||||
|
------------
|
||||||
|
NATURAL LANGUAGE RESPONSE:`);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new RunnableSequence where we pipe the output from the previous chain, the users question,
|
||||||
|
* and the SQL query, into the prompt template, and then into the llm.
|
||||||
|
* Using the result from the `sqlQueryChain` we can run the SQL query via `db.run(input.query)`.
|
||||||
|
*
|
||||||
|
* Lastly we're piping the result of the first chain (the outputted SQL query) so it is
|
||||||
|
* logged along with the natural language response.
|
||||||
|
*/
|
||||||
|
const finalChain = RunnableSequence.from([
|
||||||
|
{
|
||||||
|
question: input => input.question,
|
||||||
|
query: sqlQueryChain
|
||||||
|
},
|
||||||
|
{
|
||||||
|
schema: async () => db.getTableInfo(),
|
||||||
|
question: input => input.question,
|
||||||
|
query: input => input.query,
|
||||||
|
response: input => db.run(input.query)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
result: finalResponsePrompt.pipe(model).pipe(new StringOutputParser()),
|
||||||
|
// Pipe the query through here unchanged so it gets logged alongside the result.
|
||||||
|
sql: previousStepResult => previousStepResult.query
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
|
||||||
|
result = await finalChain.invoke({
|
||||||
|
question: question
|
||||||
});
|
});
|
||||||
|
|
||||||
result = await chain.run(question);
|
|
||||||
} else if (LLMMode === 'nochain') {
|
} else if (LLMMode === 'nochain') {
|
||||||
result = await (tools.length > 0 ? modelWithTools : model).invoke(`
|
result = await (tools.length > 0 ? modelWithTools : model).invoke(`
|
||||||
${systemPrompt}
|
${systemPrompt}
|
||||||
|
|
Loading…
Add table
Reference in a new issue