|
|
@@ -105,34 +105,54 @@ export class OrgService {
|
|
|
await this.userService.updateUser(orgUser.userId, { orgId: null })
|
|
|
}
|
|
|
|
|
|
- async ask(question: string, orgId: number, knowledgeId?: number, fileId?: number) {
|
|
|
+ async buildMessages(question: string, orgId: number, knowledgeId?: number, fileId?: number): Promise<any[]> {
|
|
|
const org = await this.findById(orgId)
|
|
|
const context = await this.knowledgeService.askKnowledge(question, orgId, knowledgeId, fileId)
|
|
|
- let content
|
|
|
- if (org.contextTemplate) {
|
|
|
- content = org.contextTemplate.replace('${context}', context.join('\n'))
|
|
|
- } else {
|
|
|
- content = dedent`You are a helpful AI article assistant.
|
|
|
- The following are the relevant article content fragments found from the article.
|
|
|
- The relevance is sorted from high to low.
|
|
|
- You can only answer according to the following content:
|
|
|
- \`\`\`
|
|
|
- ${context.join('\n')}
|
|
|
- \`\`\`
|
|
|
- You need to carefully consider your answer to ensure that it is based on the context.
|
|
|
- If the context does not mention the content or it is uncertain whether it is correct,
|
|
|
- please answer "Current context cannot provide effective information.
|
|
|
- You must use Chinese to respond.`
|
|
|
+ if (org.questionTemplate) {
|
|
|
+ question = org.questionTemplate.replace('${question}', question)
|
|
|
+ }
|
|
|
+ const messages = []
|
|
|
+ if (org.systemPrompt) {
|
|
|
+ messages.push({
|
|
|
+ role: 'system',
|
|
|
+ content: org.systemPrompt.replace('${context}', context.join('\n')).replace('${question}', question)
|
|
|
+ })
|
|
|
+ }
|
|
|
+ if (!/\$\{context\}/.test(org.systemPrompt)) {
|
|
|
+ messages.push({
|
|
|
+ role: 'user',
|
|
|
+ content: (
|
|
|
+ org.contextTemplate ||
|
|
|
+ dedent`You are a helpful AI article assistant.
|
|
|
+ The following are the relevant article content fragments found from the article.
|
|
|
+ The relevance is sorted from high to low.
|
|
|
+ You can only answer according to the following content:
|
|
|
+ \`\`\`
|
|
|
+ ${context}
|
|
|
+ \`\`\`
|
|
|
+ You need to carefully consider your answer to ensure that it is based on the context.
|
|
|
+ If the context does not mention the content or it is uncertain whether it is correct,
|
|
|
+ please answer "Current context cannot provide effective information.
|
|
|
+ You must use Chinese to respond.`
|
|
|
+ )
|
|
|
+ .replace('${context}', context.join('\n'))
|
|
|
+ .replace('${question}', question)
|
|
|
+ })
|
|
|
}
|
|
|
+ if (!/\$\{question\}/.test('' + org.systemPrompt + org.contextTemplate)) {
|
|
|
+ messages.push({
|
|
|
+ role: 'user',
|
|
|
+ content: question
|
|
|
+ })
|
|
|
+ }
|
|
|
+ return messages
|
|
|
+ }
|
|
|
|
|
|
+ async ask(question: string, orgId: number, knowledgeId?: number, fileId?: number) {
|
|
|
try {
|
|
|
const response = await this.openai.createChatCompletion({
|
|
|
model: 'gpt35',
|
|
|
- messages: [
|
|
|
- { role: 'system', content: org.systemPrompt },
|
|
|
- { role: 'user', content },
|
|
|
- { role: 'user', content: question }
|
|
|
- ]
|
|
|
+ messages: await this.buildMessages(question, orgId, knowledgeId, fileId)
|
|
|
})
|
|
|
return { answer: response.data.choices[0].message.content }
|
|
|
} catch (error) {
|
|
|
@@ -147,25 +167,6 @@ export class OrgService {
|
|
|
async streamAsk(req, res, question: string, orgId: number, knowledgeId?: number, fileId?: number) {
|
|
|
res.setHeader('Content-type', 'application/octet-stream')
|
|
|
try {
|
|
|
- const org = await this.findById(orgId)
|
|
|
- const context = await this.knowledgeService.askKnowledge(question, orgId, knowledgeId, fileId)
|
|
|
- let content
|
|
|
- if (org.contextTemplate) {
|
|
|
- content = org.contextTemplate.replace('${context}', context.join('\n'))
|
|
|
- } else {
|
|
|
- content = dedent`You are a helpful AI article assistant.
|
|
|
- The following are the relevant article content fragments found from the article.
|
|
|
- The relevance is sorted from high to low.
|
|
|
- You can only answer according to the following content:
|
|
|
- \`\`\`
|
|
|
- ${context.join('\n')}
|
|
|
- \`\`\`
|
|
|
- You need to carefully consider your answer to ensure that it is based on the context.
|
|
|
- If the context does not mention the content or it is uncertain whether it is correct,
|
|
|
- please answer "Current context cannot provide effective information.
|
|
|
- You must use Chinese to respond.`
|
|
|
- }
|
|
|
-
|
|
|
try {
|
|
|
const url = `${process.env.AZURE_OPENAI_ENDPOINT}/openai/deployments/${process.env.AZURE_OPENAI_DEPLOYMENT}/chat/completions?api-version=${process.env.AZURE_OPENAI_VERSION}`
|
|
|
let firstChunk = true
|
|
|
@@ -176,11 +177,7 @@ export class OrgService {
|
|
|
}
|
|
|
await fetchSSE(url, {
|
|
|
body: JSON.stringify({
|
|
|
- messages: [
|
|
|
- { role: 'system', content: org.systemPrompt },
|
|
|
- { role: 'user', content },
|
|
|
- { role: 'user', content: question }
|
|
|
- ],
|
|
|
+ messages: await this.buildMessages(question, orgId, knowledgeId, fileId),
|
|
|
stream: true
|
|
|
}),
|
|
|
headers: {
|