def _run(self,
messages: List[Message],
lang: Literal['en', 'zh'] = 'en',
knowledge: str = '',
**kwargs) -> Iterator[List[Message]]:
"""Q&A with RAG and tool use abilities.
Args:
knowledge: If an external knowledge string is provided,
it will be used directly without retrieving information from files in messages.
"""
# 1.将外部知识附加到系统提示中
new_messages = self._prepend_knowledge_prompt(messages=messages, lang=lang, knowledge=knowledge, **kwargs)
# 2.调用父类FnCallAgent的_run方法
return super()._run(messages=new_messages, lang=lang, **kwargs)
3.内部附加知识提示方法
(1) 参数解析
参数
参数描述
messages
传入消息列表
lang
传入消息的语言类型
knowledge
要附加到系统提示中的外部知识
(2) 代码解析:
def _prepend_knowledge_prompt(self,
messages: List[Message],
lang: Literal['en', 'zh'] = 'en',
knowledge: str = '',
**kwargs) -> List[Message]:
messages = copy.deepcopy(messages)
# 1.如果没有提供knowledge,则从配置的知识库文件中检索knowledge
if not knowledge:
# Retrieval knowledge from files
*_, last = self.mem.run(messages=messages, lang=lang, **kwargs)
knowledge = last[-1][CONTENT]
logger.debug(f'Retrieved knowledge of type `{type(knowledge).__name__}`:\n{knowledge}')
# 2.格式化knowledge为source和content
if knowledge:
knowledge = format_knowledge_to_source_and_content(knowledge)
logger.debug(f'Formatted knowledge into type `{type(knowledge).__name__}`:\n{knowledge}')
else:
knowledge = []
snippets = []
# 3.将source和content格式化为知识库提示
for k in knowledge:
snippets.append(KNOWLEDGE_SNIPPET[lang].format(source=k['source'], content=k['content']))
knowledge_prompt = ''
if snippets:
knowledge_prompt = KNOWLEDGE_TEMPLATE[lang].format(knowledge='\n\n'.join(snippets))
# 4.将知识库提示添加到消息队列中
if knowledge_prompt:
if messages[0][ROLE] == SYSTEM:
if isinstance(messages[0][CONTENT], str):
messages[0][CONTENT] += '\n\n' + knowledge_prompt
else:
assert isinstance(messages[0][CONTENT], list)
messages[0][CONTENT] += [ContentItem(text='\n\n' + knowledge_prompt)]
else:
messages = [Message(role=SYSTEM, content=knowledge_prompt)] + messages
return messages