支持私有云部署
AI知识库 AI知识库

53AI知识库

学习大模型的前沿技术与行业应用场景


AutoGen: ReAct 和 RAG
浏览次数: 1569

本文主要介绍在AutoGen中如何使用ReAct策略及RAG,如何更好的解决问题及使用本地知识库。

ReAct

ReAct(Reasoning and Acting) 是一种基于提示的范式,可以在使用LLM来进行一系列分析任务的自动执行。注意包含:ThoughtActionObservationFinal Answer

关于ReAct更多的内容可以查看这篇论文:https://arxiv.org/abs/2210.03629

下面我们来看如何在AutoGen中使用ReAct策略:

定义ReAct策略Prompts

ReAct_prompt = """尽可能回答以下问题。你可以使用提供的工具。请使用以下格式:
问题:你必须回答的输入问题
思考:你应该始终考虑该做什么
行动:要采取的行动
行动输入:对行动的输入
观察:行动的结果
...(这个过程可以多次重复)
思考:我现在知道最终答案了
最终答案:对原始输入问题的最终回答

开始!
问题:{input}
"""

定义一个方法转换ReAct策略的prompt,传入问题:

def react_prompt_message(sender, recipient, context):
    return ReAct_prompt.format(input=context["question"])

定义一个调用工具

定义一个获取医生信息的方法,返回医生名字、价格和级别;这里使用另外一种方式来注册工具,使用function_map来注册工具,需要定义工具的schema:

def get_doctor_info(subject: str) -> str:
    if subject == "骨科":
        return str([{"name""李四","price"10,"level""专家"}, {"name""赵六","price"15,"level""主任"}])
    if subject == "眼科":
        return str([{"name""张三","price"10,"level""专家"}, {"name""李四","price"15,"level""主任"}])
# 定义schema
def get_doctor_info_tool():
    # Define the function schema based on the tool's args_schema
    function_schema = {
        "name""get_doctor_info",
        "description""获取医生信息",
        "parameters": {
            "type""object",
            "properties": {
                'subject': {
                    'type''string',
                    'description''科室',
                }
            },
            "required": ['query'],
        },
    }
    return function_schema

function_schema 遵循openai规范,可参考:https://platform.openai.com/docs/api-reference/chat/create#chat-create-function_call

定义Agent并注册工具

user_proxy = autogen.UserProxyAgent(
    name="user_proxy",
    is_termination_msg=lambda x: x.get("content"""and x.get("content""").rstrip().endswith("TERMINATE"),
    human_input_mode="NEVER",
    max_consecutive_auto_reply=10,
    code_execution_config={
        "use_docker"False,
    },
)

user_proxy.register_function(
    function_map={
        "get_doctor_info": get_doctor_info
    }
)

assistant = autogen.AssistantAgent(
    name="Assistant",
    system_message="请使用提供的工具回答问题,当任务结束时回复:TERMINATE",
    llm_config={"config_list": config.config_list,
                "functions": [
                    get_doctor_info_tool(),
                ]},
)

这里也同样可以使用上一篇提到的两种方式来注册工具。

执行ReAct策略

user_proxy.initiate_chat(assistant,message=react_prompt_message,question="我腿部骨折需要看医生")

可以看到下面的输出,通过输出内容更易了解ReAct策略的运行过程和用处:

user_proxy (to Assistant):
尽可能回答以下问题。你可以使用提供的工具。请使用以下格式:
...
开始!
问题:我腿部骨折需要看医生
--------------------------------------------------------------------------------
Assistant (to user_proxy):
思考:需要找出处理骨折的医生,一般来说,这是骨科医生的职责。
行动:用提供的工具来找出医生信息。
行动输入:{'subject': '骨科'}
***** Suggested function call: get_doctor_info *****
Arguments: 
{
"subject": "骨科"
}
****************************************************
--------------------------------------------------------------------------------
>>>>>>>> EXECUTING FUNCTION get_doctor_info...
user_proxy (to Assistant):
***** Response from calling function (get_doctor_info) *****
[{'name': '李四', 'price': 10, 'level': '专家'}, {'name': '赵六', 'price': 15, 'level': '主任'}]
************************************************************
--------------------------------------------------------------------------------
Assistant (to user_proxy):
观察:找到了两位骨科医生,一个是专家级别的李四,花费是10,另一个是主任级别的赵六,花费是15。
思考:我现在知道最终答案了。
最终答案:你可以选择李四医生或赵六医生进行诊疗,李四是骨科的专家,费用为10,赵六是骨科主任,费用为15。
TERMINATE
--------------------------------------------------------------------------------
Process finished with exit code 0

另外,Teachability使用向量库可以使Agent记住用户所给予的信息,从而可以更轻松地回答类似的问题。类似于给了Agent一个备忘录,当使用teachability.add_to_agent(agent)时,再次提问,Agent将会直接给出答案。

RAG

RAG(Retrieval Augmented Generation),检索增强将语言模型与外部知识检索相结合,以提高生成响应的质量和相关性。在AutoGen中提供了RetrieveUserProxyAgentRetrieveUserProxyAgent支持RAG。

构建embedding_function与文本拆分器

RAG数据准备大致分为四个阶段:数据提取文本分割向量化数据入库

openai_embedding_function = embedding_functions.OpenAIEmbeddingFunction(api_key="",api_base="",api_type="",api_version="",model_name="text-embedding-ada-002")
text_splitter = RecursiveCharacterTextSplitter(separators=["\n\n""\n""\r""\t"])

构建智能体

assistant = RetrieveAssistantAgent(
    name="assistant",
    system_message="You are a helpful assistant.",
    llm_config={
        "timeout"600,
        "cache_seed"42,
        "config_list": config.config_list,
    },
)

ragproxyagent = RetrieveUserProxyAgent(
    name="ragproxyagent",
    human_input_mode="NEVER",
    max_consecutive_auto_reply=3,
    retrieve_config={
        "task""qa",
        "docs_path": [
            "https://xxxx.md",
            os.path.join(os.path.abspath(""), ".""file""info.md"),
        ],
        "chunk_token_size"2000,
        "model": config.config_list[0]["model"],
        "client": chromadb.PersistentClient(path="/tmp/chromadb"),
        "embedding_model""text-embedding-ada-002",
        "must_break_at_empty_line"False,
        "get_or_create"True,
        "embedding_function": openai_embedding_function,
        "custom_text_split_function": text_splitter.split_text,
        "collection_name""my-test"
    },
    code_execution_config=False
)

retrieve_config(dict 或 None):检索代理的配置,参数介绍:

  • task (可选,str) - 检索聊天的任务。可能的值有"code", "qa" 和 "default"。不同任务的系统提示将不同。默认值是 default,它支持代码和问答。
  • client (可选,chromadb.Client) - chromadb 客户端。如果未提供此键,将使用默认客户端 chromadb.Client()。如果您想使用其他向量数据库,请扩展此类并重写 retrieve_docs 函数。
  • docs_path (可选,Union[str, List[str]]) - 文档目录的路径。它还可以是单个文件的路径,单个文件的网址或一系列目录、文件和网址的路径。默认为 None,仅在已创建集合的情况下有效。
  • extra_docs (可选,bool) - 当为 true 时,允许添加具有唯一 ID 的文档而不会覆盖现有的;当为 false 时,它使用默认 ID 替换现有文档,存在覆盖集合的风险。当设置为 true 时,它允许系统为新的文档片段分配唯一的 ID,从 "length+i" 开始,防止替换现有文档并便于向集合添加更多内容。默认情况下,"extra_docs" 设置为 false,从零开始文档 ID。
  • collection_name (可选,str) - 集合的名称。如果未提供此键,将使用默认名称 autogen-docs
  • model (可选,str) - 用于检索聊天的模型。如果未提供此键,将使用默认模型 gpt-4
  • chunk_token_size (可选,int) - 检索聊天的块令牌大小。如果未提供此键,将使用默认大小 max_tokens * 0.4
  • context_max_tokens (可选,int) - 检索聊天的上下文最大令牌大小。如果未提供此键,将使用默认大小 max_tokens * 0.8
  • chunk_mode (可选,str) - 检索聊天的块模式。可能的值是 "multi_lines" 和 "one_line"。如果未提供此键,将使用默认模式multi_lines
  • must_break_at_empty_line (可选,bool) - 如果为 True,则块将只在空行处分隔。默认为 True。如果 chunk_mode 为 "one_line",此参数将被忽略。
  • embedding_model (可选,str) - 用于检索聊天的嵌入模型。如果未提供此键,将使用默认模型 all-MiniLM-L6-v2。推荐使用 all-mpnet-base-v2
  • embedding_function (可选,Callable) - 创建向量数据库的嵌入函数。默认值为 None,将使用给定的 embedding_model的 SentenceTransformer。按照 https://docs.trychroma.com/embeddings 中的示例操作。
  • customized_prompt (可选,str) - 检索聊天的自定义提示。默认值为 None。
  • customized_answer_prefix (可选,str) - 检索聊天的自定义答案前缀。默认为空字符串。如果不为空字符串并且答案中没有包含 customized_answer_prefix,将触发 Update Context
  • update_context (可选,bool) - 如果为 False,将不会对互动检索应用Update Context。默认为 True。
  • get_or_create (可选,bool) - 如果为 True,将为检索聊天创建/返回一个集合。这与 chromadb 中使用的相同。默认值为 False。如果集合已存在且get_or_create 为 False,则会引发 ValueError。如果 docs_path 为 None,则会设置为 True。
  • custom_token_count_function (可选,Callable) - 自定义函数,用于计算字符串中的令牌数量。函数应该接受 (text:str, model:str) 作为输入并返回令牌数量(int)。retrieve_config["model"] 将被传递到函数中。默认为autogen.token_count_utils.count_token 使用 tiktoken
  • custom_text_split_function (可选,Callable) - 自定义函数,用于将字符串分割成字符串列表。默认值为 None,将使用 autogen.retrieve_utils.split_text_to_chunks 中的默认函数。
  • custom_text_types (可选,List[str]) - 要处理的文件类型列表。默认值为 autogen.retrieve_utils.TEXT_FORMATS。这仅适用于 docs_path 下目录中的文件。明确包括的文件和网址将进行分块,无论其类型如何。
  • recursive (可选,bool) - 是否在 docs_path 中递归搜索文档。默认为 True。

执行问答

ragproxyagent.initiate_chat(assistant, message=ragproxyagent.message_generator, problem='总结下文档信息,介绍下企业情况', search_string="code", n_results=2)

输出如下:

Trying to create collection.
doc_ids:  [['doc_1', 'doc_2']]
Adding doc_id doc_1 to context.
Adding doc_id doc_2 to context.
...
User's question is: 总结下文档信息,介绍下企业情况
...
assistant (to ragproxyagent):
这是一个由Hugging Face组织的项目,旨在开发最佳的句子嵌入模型...。文档无法提供任何关于企业的情况。

可以看到在AutoGen中RetrieveUserProxyAgent首先自动处理文档,拆分、分块并将它们存储在矢量数据库中。然后,对于给定的用户输入,它会检索相关块作为上下文并将其发送到RetrieveAssistantAgent,RetrieveAssistantAgent使用 LLM 生成代码或文本来回答问题。Agent交谈,直到他们找到满意的答案。 

此外,AutoGen中也添加了QdrantRetrieveUserProxyAgent使用 qdrant 作为向量数据库; 集成了 UNSTRUCTURED 来支持许多非结构化文档。关于 RAG的内容,Autogen 仍然在快速迭代中。

推荐新闻
RAG系列04:使用ReRank进行重排序
本文介绍了重排序的原理和两种主流的重排序方法:基于重排模型和基于 LLM。文章指出,重排序是对检索到的上下文进行再次筛选的过程,类似于排序过程中的粗排和精排。在检索增强生成中,精排的术语就叫重排序。文章还介绍了使用 Cohere 提供的在线模型、bge-reranker-base 和 bge-reranker-large 等开源模型以及 LLM 实现重排序的方法。最后,文章得出结论:使用重排模型的方法轻量级、开销较小;而使用 LLM 的方法在多个基准测试上表现良好,但成本较高,且只有在使用 ChatGPT 和 GPT-4 时表现良好,如使用其他开源模型,如 FLAN-T5 和 Vicuna-13B 时,其性能就不那么理想。因此,在实际项目中,需要做出特定的权衡。
LangGPT论文:面向大语言模型的自然语言编程框架(中文版)
大语言模型 (Large Language Models, LLMs) 在不同领域都表现出了优异的性能。然而,对于非AI专家来说,制定高质量的提示来引导 LLMs 是目前AI应用领域的一项重要挑战。
第三篇:要真正入门AI,OpenAI的官方Prompt工程指南肯定还不够,您必须了解的强大方法论和框架!!!
自从ChatGPT(全名:Chat Generative Pre-trained Transformer)于2022年11月30日发布以来,一个新兴的行业突然兴起,那就是提示工程(Prompt engineering),可谓如日冲天。从简单的文章扩写,到RAG,ChatGPT展现了前所未有的惊人能力。
(三)12个RAG痛点及其解决方案
痛点9:结构化数据QA 痛点10:从复杂 PDF 中提取数据 痛点11:后备模型 痛点12:LLM安全
(二)12个RAG痛点及其解决方案
痛点5:格式错误 痛点6:不正确的特异性 痛点7:不完整 痛点8:数据摄取可扩展性

联系我们

售前咨询
186 6662 7370
产品演示
185 8882 0121

微信扫码

与创始人交个朋友

回到顶部

 
扫码咨询