
本案例灵感来源于OpenAI DevDay 2023上展示的GPTs界面。它演示了如何使用自然语言构建一个代理更特别的是您可以使用另一个代理来构建您自己的代理1. 案例目标本案例的主要目标是创建一个代理构建器它能够根据用户的自然语言描述自动生成并配置一个专门的代理来执行特定任务。这个构建器代理将理解用户的任务描述为任务生成合适的系统提示从预定义工具集中检索相关工具创建并配置一个专门的任务执行代理2. 技术栈与核心依赖LlamaIndex- 用于构建代理和工具检索系统OpenAI API- 提供语言模型和嵌入模型FunctionAgent- 用于构建可执行工具调用的代理ObjectIndex- 用于工具的向量化索引和检索VectorStoreIndex- 用于文档的向量化索引核心依赖包%pip install llama-index-embeddings-openai %pip install llama-index-llms-openai %pip install llama-index-readers-file3. 环境配置首先需要设置OpenAI API密钥import os os.environ[OPENAI_API_KEY] sk-...然后配置LlamaIndex的全局默认设置from llama_index.embeddings.openai import OpenAIEmbedding from llama_index.llms.openai import OpenAI from llama_index.core import Settings llm OpenAI(modelgpt-4o) Settings.llm llm Settings.embed_model OpenAIEmbedding(modeltext-embedding-3-small)4. 案例实现4.1 定义候选工具在这个设置中我们将工具定义为不同的维基百科页面。首先我们获取几个城市的维基百科内容from llama_index.core import SimpleDirectoryReader from pathlib import Path import requests wiki_titles [Toronto, Seattle, Chicago, Boston, Houston] for title in wiki_titles: response requests.get( https://en.wikipedia.org/w/api.php, params{ action: query, format: json, titles: title, prop: extracts, explaintext: True, }, ).json() page next(iter(response[query][pages].values())) wiki_text page[extract] data_path Path(data) if not data_path.exists(): Path.mkdir(data_path) with open(data_path / f{title}.txt, w) as fp: fp.write(wiki_text)加载所有维基百科文档# 加载所有维基百科文档 city_docs {} for wiki_title in wiki_titles: city_docs[wiki_title] SimpleDirectoryReader( input_files[fdata/{wiki_title}.txt] ).load_data()4.2 为每个文档构建查询工具from llama_index.core import VectorStoreIndex from llama_index.core.tools import QueryEngineTool # 构建工具字典 tool_dict {} for wiki_title in wiki_titles: # 构建向量索引 vector_index VectorStoreIndex.from_documents( city_docs[wiki_title], ) # 定义查询引擎 vector_query_engine vector_index.as_query_engine(llmllm) # 定义工具 vector_tool QueryEngineTool.from_defaults( query_enginevector_query_engine, namewiki_title, description(Useful for questions related to f {wiki_title}), ) tool_dict[wiki_title] vector_tool4.3 定义工具检索器# 在这些工具上定义一个对象索引和检索器 from llama_index.core import VectorStoreIndex from llama_index.core.objects import ObjectIndex tool_index ObjectIndex.from_objects( list(tool_dict.values()), index_clsVectorStoreIndex, ) tool_retriever tool_index.as_retriever(similarity_top_k1)4.4 定义GPT构建器的元工具我们定义三个核心函数用于构建代理的各个组件from llama_index.core.agent.workflow import FunctionAgent from llama_index.core.llms import ChatMessage from llama_index.core import ChatPromptTemplate from typing import List GEN_SYS_PROMPT_STR \ Task information is given below. Given the task, please generate a system prompt for an OpenAI-powered bot to solve this task: {task} \ gen_sys_prompt_messages [ ChatMessage( rolesystem, contentYou are helping to build a system prompt for another bot., ), ChatMessage(roleuser, contentGEN_SYS_PROMPT_STR), ] GEN_SYS_PROMPT_TMPL ChatPromptTemplate(gen_sys_prompt_messages) agent_cache {} async def create_system_prompt(task: str): Create system prompt for another agent given an input task. llm OpenAI(llmgpt-4) fmt_messages GEN_SYS_PROMPT_TMPL.format_messages(tasktask) response await llm.achat(fmt_messages) return response.message.content async def get_tools(task: str): Get the set of relevant tools to use given an input task. subset_tools await tool_retriever.aretrieve(task) return [t.metadata.name for t in subset_tools] def create_agent(system_prompt: str, tool_names: List[str]): Create an agent given a system prompt and an input set of tools. llm OpenAI(modelgpt-4o) try: # 获取工具列表 input_tools [tool_dict[tn] for tn in tool_names] agent FunctionAgent( toolsinput_tools, llmllm, system_promptsystem_prompt ) agent_cache[agent] agent return_msg Agent created successfully. except Exception as e: return_msg fAn error occurred when building an agent. Here is the error: {repr(e)} return return_msg将这些函数转换为工具from llama_index.core.tools import FunctionTool system_prompt_tool FunctionTool.from_defaults(fncreate_system_prompt) get_tools_tool FunctionTool.from_defaults(fnget_tools) create_agent_tool FunctionTool.from_defaults(fncreate_agent)4.5 创建构建器代理GPT_BUILDER_SYS_STR \ You are helping to construct an agent given a user-specified task. You should generally use the tools in this order to build the agent. 1) Create system prompt tool: to create the system prompt for the agent. 2) Get tools tool: to fetch the candidate set of tools to use. 3) Create agent tool: to create the final agent. prefix_msgs [ChatMessage(rolesystem, contentGPT_BUILDER_SYS_STR)] builder_agent FunctionAgent( tools[system_prompt_tool, get_tools_tool, create_agent_tool], prefix_messagesprefix_msgs, llmOpenAI(modelgpt-4o), verboseTrue, )5. 案例效果5.1 使用构建器代理创建新代理from llama_index.core.agent.workflow import ToolCallResult handler builder_agent.run(Build an agent that can tell me about Toronto.) async for event in handler.stream_events(): if isinstance(event, ToolCallResult): print( fCalled tool {event.tool_name} with input {event.tool_kwargs}\nGot output: {event.tool_output} ) result await handler print(fResult: {result})预期输出Called tool create_system_prompt with input {task: Tell me about Toronto} Got output: Generate a brief summary about Toronto, including its history, culture, landmarks, and notable features. Called tool get_tools with input {task: Tell me about Toronto} Got output: [Toronto] Called tool create_agent with input {system_prompt: Generate a brief summary about Toronto, including its history, culture, landmarks, and notable features., tool_names: [Toronto]} Got output: Agent created successfully. Result: I have created an agent that can provide information about Toronto, including its history, culture, landmarks, and notable features. You can now ask the agent any questions you have about Toronto!5.2 使用新创建的代理city_agent agent_cache[agent] response await city_agent.run(Tell me about the parks in Toronto) print(str(response))预期输出Toronto is home to a diverse array of parks and public spaces, offering both urban and natural environments. Key downtown parks include Allan Gardens, Christie Pits, and Trinity Bellwoods Park. For waterfront views, Tommy Thompson Park and the Toronto Islands are popular destinations. In the citys outer areas, large parks like High Park, Humber Bay Park, and Morningside Park provide expansive green spaces. Additionally, parts of Rouge National Urban Park, the largest urban park in North America, are located within Toronto. The city also features notable squares such as Nathan Phillips Square, Yonge–Dundas Square, and Harbourfront Square. Approximately 12.5% of Torontos land is dedicated to parkland, offering facilities for various activities, including winter sports like ice skating and skiing.6. 案例实现思路6.1 代理构建流程本案例的核心是一个三步代理构建流程创建系统提示使用LLM根据任务描述生成合适的系统提示获取相关工具使用向量检索从预定义工具集中检索与任务相关的工具创建代理使用系统提示和相关工具创建最终的执行代理6.2 工具检索机制案例使用ObjectIndex将工具向量化使构建器代理能够根据任务描述检索最相关的工具。这种机制允许代理根据任务需求动态选择工具而不是硬编码固定的工具集。6.3 代理缓存机制通过agent_cache字典新创建的代理被保存起来以便后续使用。这种设计允许构建器代理创建多个专门的代理并在需要时检索它们。6.4 分层代理架构案例展示了一种分层代理架构其中构建器代理(高层)负责创建和管理任务执行代理(低层)。这种架构允许更灵活和动态的代理系统可以根据不同任务创建专门的代理。7. 扩展建议7.1 扩展工具集添加更多类型的工具如API调用工具、数据库查询工具、计算工具等实现工具的自动发现和注册机制使系统能够动态添加新工具创建工具分类体系提高工具检索的精确度7.2 增强构建器代理能力实现更复杂的系统提示生成策略考虑任务类型、用户偏好等因素添加代理性能评估机制允许构建器代理优化生成的代理实现代理迭代改进功能根据用户反馈调整代理配置7.3 多代理协作设计代理间通信协议使多个专门代理能够协作解决复杂任务实现代理工作流编排功能允许定义多步骤任务的处理流程添加代理市场功能允许用户分享和发现预构建的专门代理7.4 用户界面与交互开发图形界面简化代理创建和配置过程实现代理性能监控和分析工具添加代理使用教程和示例库帮助用户快速上手8. 总结本案例展示了一种创新的代理构建方法通过使用一个元代理来创建和管理其他专门代理。这种方法的核心优势在于动态性系统能够根据任务需求动态创建和配置代理而不是使用静态预定义代理灵活性通过工具检索机制代理可以灵活选择最适合的工具组合可扩展性分层架构使系统易于扩展可以添加新工具和新类型的代理自动化整个代理创建过程高度自动化用户只需提供自然语言任务描述这种方法为构建更智能、更自适应的AI系统提供了一种有前景的路径。它展示了如何利用LLMs的理解和生成能力创建能够自我配置和适应的代理系统。未来这种代理构建代理的范式可能会成为构建复杂AI应用的标准方法特别是在需要处理多样化任务和动态变化的场景中。