AutoGen: ReAct 和 RAG

关注公众号:闲人张,了解更多内容:

AutoGen入门学习:hello world!

AutoGen: 代码执行与工具调用

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

ReAct

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

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

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

定义ReAct策略Prompts

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

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

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

python 复制代码
def react_prompt_message(sender, recipient, context):
    return ReAct_prompt.format(input=context["question"])

定义一个调用工具

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

python 复制代码
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规范,可参考:platform.openai.com/docs/api-re...

定义Agent并注册工具

ini 复制代码
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策略

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

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

markdown 复制代码
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数据准备大致分为四个阶段:数据提取、文本分割、向量化、数据入库

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

构建智能体

lua 复制代码
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。

执行问答

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

输出如下:

vbnet 复制代码
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 仍然在快速迭代中。

解锁更多精彩关注公众号:闲人张

相关推荐
灰太狼不爱写代码5 分钟前
CUDA11.4版本的Pytorch下载
人工智能·pytorch·笔记·python·学习
volcanical2 小时前
Dataset Distillation with Attention Labels for Fine-tuning BERT
人工智能·深度学习·bert
L_cl2 小时前
【NLP 17、NLP的基础——分词】
人工智能·自然语言处理
西西弗Sisyphus2 小时前
大型语言模型(LLMs)演化树 Large Language Models
人工智能·语言模型·自然语言处理·大模型
车载诊断技术4 小时前
电子电气架构 --- 什么是EPS?
网络·人工智能·安全·架构·汽车·需求分析
KevinRay_4 小时前
Python超能力:高级技巧让你的代码飞起来
网络·人工智能·python·lambda表达式·列表推导式·python高级技巧
跃跃欲试-迪之4 小时前
animatediff 模型网盘分享
人工智能·stable diffusion
Captain823Jack5 小时前
nlp新词发现——浅析 TF·IDF
人工智能·python·深度学习·神经网络·算法·自然语言处理
被制作时长两年半的个人练习生5 小时前
【AscendC】ReduceSum中指定workLocal大小时如何计算
人工智能·算子开发·ascendc
Captain823Jack5 小时前
w04_nlp大模型训练·中文分词
人工智能·python·深度学习·神经网络·算法·自然语言处理·中文分词