### What problem does this PR solve? This is a follow-up of #7088 , adding a knowledge base type input to the `Begin` component, and a knowledge base selector to the agent flow debug input panel:  then you can select one or more knowledge bases when testing the agent:  Note: the lines changed in `agent/component/retrieval.py` after line 94 are modified by `ruff format` from the `pre-commit` hooks, no functional change. ### Type of change - [ ] Bug Fix (non-breaking change which fixes an issue) - [x] New Feature (non-breaking change which adds functionality) - [ ] Documentation Update - [ ] Refactoring - [ ] Performance Improvement - [ ] Other (please describe):tags/v0.19.0
| @@ -30,10 +30,10 @@ from rag.utils.tavily_conn import Tavily | |||
| class RetrievalParam(ComponentParamBase): | |||
| """ | |||
| Define the Retrieval component parameters. | |||
| """ | |||
| def __init__(self): | |||
| super().__init__() | |||
| self.similarity_threshold = 0.2 | |||
| @@ -67,7 +67,10 @@ class Retrieval(ComponentBase, ABC): | |||
| if len(kb_vars) > 0: | |||
| for kb_var in kb_vars: | |||
| if len(kb_var) == 1: | |||
| kb_ids.append(str(kb_var["content"][0])) | |||
| kb_var_value = str(kb_var["content"][0]) | |||
| for v in kb_var_value.split(","): | |||
| kb_ids.append(v) | |||
| else: | |||
| for v in kb_var.to_dict("records"): | |||
| kb_ids.append(v["content"]) | |||
| @@ -91,20 +94,24 @@ class Retrieval(ComponentBase, ABC): | |||
| rerank_mdl = LLMBundle(kbs[0].tenant_id, LLMType.RERANK, self._param.rerank_id) | |||
| if kbs: | |||
| kbinfos = settings.retrievaler.retrieval(query, embd_mdl, kbs[0].tenant_id, filtered_kb_ids, | |||
| 1, self._param.top_n, | |||
| self._param.similarity_threshold, 1 - self._param.keywords_similarity_weight, | |||
| aggs=False, rerank_mdl=rerank_mdl, | |||
| rank_feature=label_question(query, kbs)) | |||
| kbinfos = settings.retrievaler.retrieval( | |||
| query, | |||
| embd_mdl, | |||
| kbs[0].tenant_id, | |||
| filtered_kb_ids, | |||
| 1, | |||
| self._param.top_n, | |||
| self._param.similarity_threshold, | |||
| 1 - self._param.keywords_similarity_weight, | |||
| aggs=False, | |||
| rerank_mdl=rerank_mdl, | |||
| rank_feature=label_question(query, kbs), | |||
| ) | |||
| else: | |||
| kbinfos = {"chunks": [], "doc_aggs": []} | |||
| if self._param.use_kg and kbs: | |||
| ck = settings.kg_retrievaler.retrieval(query, | |||
| [kbs[0].tenant_id], | |||
| filtered_kb_ids, | |||
| embd_mdl, | |||
| LLMBundle(kbs[0].tenant_id, LLMType.CHAT)) | |||
| ck = settings.kg_retrievaler.retrieval(query, [kbs[0].tenant_id], filtered_kb_ids, embd_mdl, LLMBundle(kbs[0].tenant_id, LLMType.CHAT)) | |||
| if ck["content_with_weight"]: | |||
| kbinfos["chunks"].insert(0, ck) | |||
| @@ -123,5 +130,3 @@ class Retrieval(ComponentBase, ABC): | |||
| df = pd.DataFrame({"content": kb_prompt(kbinfos, 200000), "chunks": json.dumps(kbinfos["chunks"])}) | |||
| logging.debug("{} {}".format(query, df)) | |||
| return df.dropna() | |||
| @@ -10,13 +10,17 @@ import { FormControl, FormField, FormItem, FormLabel } from './ui/form'; | |||
| import { MultiSelect } from './ui/multi-select'; | |||
| interface KnowledgeBaseItemProps { | |||
| label?: string; | |||
| tooltipText?: string; | |||
| name?: string; | |||
| required?: boolean; | |||
| onChange?(): void; | |||
| } | |||
| const KnowledgeBaseItem = ({ | |||
| label, | |||
| tooltipText, | |||
| name, | |||
| required = true, | |||
| onChange, | |||
| }: KnowledgeBaseItemProps) => { | |||
| @@ -40,8 +44,8 @@ const KnowledgeBaseItem = ({ | |||
| return ( | |||
| <Form.Item | |||
| label={t('knowledgeBases')} | |||
| name="kb_ids" | |||
| label={label || t('knowledgeBases')} | |||
| name={name || 'kb_ids'} | |||
| tooltip={tooltipText || t('knowledgeBasesTip')} | |||
| rules={[ | |||
| { | |||
| @@ -56,6 +56,7 @@ import upperFirst from 'lodash/upperFirst'; | |||
| import { | |||
| CirclePower, | |||
| CloudUpload, | |||
| Database, | |||
| IterationCcw, | |||
| ListOrdered, | |||
| OptionIcon, | |||
| @@ -2949,6 +2950,7 @@ export enum BeginQueryType { | |||
| File = 'file', | |||
| Integer = 'integer', | |||
| Boolean = 'boolean', | |||
| KnowledgeBases = 'kb', | |||
| } | |||
| export const BeginQueryTypeIconMap = { | |||
| @@ -2958,6 +2960,7 @@ export const BeginQueryTypeIconMap = { | |||
| [BeginQueryType.File]: CloudUpload, | |||
| [BeginQueryType.Integer]: ListOrdered, | |||
| [BeginQueryType.Boolean]: ToggleLeft, | |||
| [BeginQueryType.KnowledgeBases]: Database, | |||
| }; | |||
| export const NoDebugOperatorsList = [ | |||
| @@ -25,6 +25,7 @@ import { BeginQuery } from '../interface'; | |||
| import { PopoverForm } from './popover-form'; | |||
| import styles from './index.less'; | |||
| import KnowledgeBaseItem from '@/components/knowledge-base-item'; | |||
| interface IProps { | |||
| parameters: BeginQuery[]; | |||
| @@ -164,6 +165,13 @@ const DebugContent = ({ | |||
| <Switch></Switch> | |||
| </Form.Item> | |||
| ), | |||
| [BeginQueryType.KnowledgeBases]: ( | |||
| <KnowledgeBaseItem | |||
| name={idx.toString()} | |||
| label={q.name || q.key} | |||
| required={!q.optional} | |||
| ></KnowledgeBaseItem> | |||
| ) | |||
| }; | |||
| return ( | |||
| @@ -182,12 +190,16 @@ const DebugContent = ({ | |||
| if (Array.isArray(value)) { | |||
| nextValue = ``; | |||
| value.forEach((x) => { | |||
| nextValue += | |||
| x?.originFileObj instanceof File | |||
| ? `${x.name}\n${x.response?.data}\n----\n` | |||
| : `${x.url}\n${x.result}\n----\n`; | |||
| }); | |||
| if (item.type === 'kb') { | |||
| nextValue = value.join(',') | |||
| } else { | |||
| value.forEach((x) => { | |||
| nextValue += | |||
| x?.originFileObj instanceof File | |||
| ? `${x.name}\n${x.response?.data}\n----\n` | |||
| : `${x.url}\n${x.result}\n----\n`; | |||
| }); | |||
| } | |||
| } | |||
| return { ...item, value: nextValue }; | |||
| }); | |||