Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 24382d6

Browse files
committedMar 15, 2025·
fix KnowledgeBase search issue
1 parent 1a6485d commit 24382d6

File tree

4 files changed

+95
-69
lines changed

4 files changed

+95
-69
lines changed
 

‎src/database/server/models/chunk.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,8 @@ export class ChunkModel {
207207
.leftJoin(files, eq(files.id, fileChunks.fileId))
208208
.where(inArray(fileChunks.fileId, fileIds))
209209
.orderBy((t) => desc(t.similarity))
210-
.limit(5);
210+
// 先放宽到 15
211+
.limit(15);
211212

212213
return result.map((item) => {
213214
return {

‎src/server/routers/lambda/agent.ts

+10-7
Original file line numberDiff line numberDiff line change
@@ -122,13 +122,16 @@ export const agentRouter = router({
122122
const knowledge = await ctx.agentModel.getAgentAssignedKnowledge(input.agentId);
123123

124124
return [
125-
...files.map((file) => ({
126-
enabled: knowledge.files.some((item) => item.id === file.id),
127-
fileType: file.fileType,
128-
id: file.id,
129-
name: file.name,
130-
type: KnowledgeType.File,
131-
})),
125+
...files
126+
// 过滤掉所有图片
127+
.filter((file) => !file.fileType.startsWith('image'))
128+
.map((file) => ({
129+
enabled: knowledge.files.some((item) => item.id === file.id),
130+
fileType: file.fileType,
131+
id: file.id,
132+
name: file.name,
133+
type: KnowledgeType.File,
134+
})),
132135
...knowledgeBases.map((knowledgeBase) => ({
133136
avatar: knowledgeBase.avatar,
134137
description: knowledgeBase.description,

‎src/server/routers/lambda/chunk.ts

+65-49
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { TRPCError } from '@trpc/server';
12
import { inArray } from 'drizzle-orm/expressions';
23
import { z } from 'zod';
34

@@ -126,60 +127,75 @@ export const chunkRouter = router({
126127
semanticSearchForChat: chunkProcedure
127128
.input(SemanticSearchSchema)
128129
.mutation(async ({ ctx, input }) => {
129-
const item = await ctx.messageModel.findMessageQueriesById(input.messageId);
130-
const { model, provider } =
131-
getServerDefaultFilesConfig().embeddingModel || DEFAULT_FILE_EMBEDDING_MODEL_ITEM;
132-
let embedding: number[];
133-
let ragQueryId: string;
134-
// if there is no message rag or it's embeddings, then we need to create one
135-
if (!item || !item.embeddings) {
136-
// TODO: need to support customize
137-
const agentRuntime = await initAgentRuntimeWithUserPayload(provider, ctx.jwtPayload);
138-
139-
const embeddings = await agentRuntime.embeddings({
140-
dimensions: 1024,
141-
input: input.rewriteQuery,
142-
model,
143-
});
144-
145-
embedding = embeddings![0];
146-
const embeddingsId = await ctx.embeddingModel.create({
147-
embeddings: embedding,
148-
model,
130+
try {
131+
const item = await ctx.messageModel.findMessageQueriesById(input.messageId);
132+
const { model, provider } =
133+
getServerDefaultFilesConfig().embeddingModel || DEFAULT_FILE_EMBEDDING_MODEL_ITEM;
134+
let embedding: number[];
135+
let ragQueryId: string;
136+
137+
// if there is no message rag or it's embeddings, then we need to create one
138+
if (!item || !item.embeddings) {
139+
// TODO: need to support customize
140+
const agentRuntime = await initAgentRuntimeWithUserPayload(provider, ctx.jwtPayload);
141+
142+
// slice content to make sure in the context window limit
143+
const query =
144+
input.rewriteQuery.length > 8000
145+
? input.rewriteQuery.slice(0, 8000)
146+
: input.rewriteQuery;
147+
148+
const embeddings = await agentRuntime.embeddings({
149+
dimensions: 1024,
150+
input: query,
151+
model,
152+
});
153+
154+
embedding = embeddings![0];
155+
const embeddingsId = await ctx.embeddingModel.create({
156+
embeddings: embedding,
157+
model,
158+
});
159+
160+
const result = await ctx.messageModel.createMessageQuery({
161+
embeddingsId,
162+
messageId: input.messageId,
163+
rewriteQuery: input.rewriteQuery,
164+
userQuery: input.userQuery,
165+
});
166+
167+
ragQueryId = result.id;
168+
} else {
169+
embedding = item.embeddings;
170+
ragQueryId = item.id;
171+
}
172+
173+
let finalFileIds = input.fileIds ?? [];
174+
175+
if (input.knowledgeIds && input.knowledgeIds.length > 0) {
176+
const knowledgeFiles = await serverDB.query.knowledgeBaseFiles.findMany({
177+
where: inArray(knowledgeBaseFiles.knowledgeBaseId, input.knowledgeIds),
178+
});
179+
180+
finalFileIds = knowledgeFiles.map((f) => f.fileId).concat(finalFileIds);
181+
}
182+
183+
const chunks = await ctx.chunkModel.semanticSearchForChat({
184+
embedding,
185+
fileIds: finalFileIds,
186+
query: input.rewriteQuery,
149187
});
150188

151-
const result = await ctx.messageModel.createMessageQuery({
152-
embeddingsId,
153-
messageId: input.messageId,
154-
rewriteQuery: input.rewriteQuery,
155-
userQuery: input.userQuery,
156-
});
189+
// TODO: need to rerank the chunks
157190

158-
ragQueryId = result.id;
159-
} else {
160-
embedding = item.embeddings;
161-
ragQueryId = item.id;
162-
}
191+
return { chunks, queryId: ragQueryId };
192+
} catch (e) {
193+
console.error(e);
163194

164-
console.time('semanticSearch');
165-
let finalFileIds = input.fileIds ?? [];
166-
167-
if (input.knowledgeIds && input.knowledgeIds.length > 0) {
168-
const knowledgeFiles = await serverDB.query.knowledgeBaseFiles.findMany({
169-
where: inArray(knowledgeBaseFiles.knowledgeBaseId, input.knowledgeIds),
195+
throw new TRPCError({
196+
code: 'INTERNAL_SERVER_ERROR',
197+
message: (e as any).errorType || JSON.stringify(e),
170198
});
171-
172-
finalFileIds = knowledgeFiles.map((f) => f.fileId).concat(finalFileIds);
173199
}
174-
175-
const chunks = await ctx.chunkModel.semanticSearchForChat({
176-
embedding,
177-
fileIds: finalFileIds,
178-
query: input.rewriteQuery,
179-
});
180-
// TODO: need to rerank the chunks
181-
console.timeEnd('semanticSearch');
182-
183-
return { chunks, queryId: ragQueryId };
184200
}),
185201
});

‎src/store/chat/slices/aiChat/actions/rag.ts

+18-12
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ export interface ChatRAGAction {
2121
id: string,
2222
userQuery: string,
2323
messages: string[],
24-
) => Promise<{ chunks: ChatSemanticSearchChunk[]; queryId: string; rewriteQuery?: string }>;
24+
) => Promise<{ chunks: ChatSemanticSearchChunk[]; queryId?: string; rewriteQuery?: string }>;
2525
/**
2626
* Rewrite user content to better RAG query
2727
*/
@@ -74,17 +74,23 @@ export const chatRag: StateCreator<ChatStore, [['zustand/devtools', never]], [],
7474

7575
// 2. retrieve chunks from semantic search
7676
const files = chatSelectors.currentUserFiles(get()).map((f) => f.id);
77-
const { chunks, queryId } = await ragService.semanticSearchForChat({
78-
fileIds: knowledgeIds().fileIds.concat(files),
79-
knowledgeIds: knowledgeIds().knowledgeBaseIds,
80-
messageId: id,
81-
rewriteQuery: rewriteQuery || userQuery,
82-
userQuery,
83-
});
84-
85-
get().internal_toggleMessageRAGLoading(false, id);
86-
87-
return { chunks, queryId, rewriteQuery };
77+
try {
78+
const { chunks, queryId } = await ragService.semanticSearchForChat({
79+
fileIds: knowledgeIds().fileIds.concat(files),
80+
knowledgeIds: knowledgeIds().knowledgeBaseIds,
81+
messageId: id,
82+
rewriteQuery: rewriteQuery || userQuery,
83+
userQuery,
84+
});
85+
86+
get().internal_toggleMessageRAGLoading(false, id);
87+
88+
return { chunks, queryId, rewriteQuery };
89+
} catch {
90+
get().internal_toggleMessageRAGLoading(false, id);
91+
92+
return { chunks: [] };
93+
}
8894
},
8995
internal_rewriteQuery: async (id, content, messages) => {
9096
let rewriteQuery = content;

0 commit comments

Comments
 (0)
Please sign in to comment.