大语言模型代理是自动化搜索,内容生成和质量审查等任务的强大工具。但是,单个代理通常无法有效地做所有事情,尤其是当您需要集成外部资源(例如Web搜索)和多个专业步骤(例如,起草与审查)时。多代理工作流程使您可以将这些任务分配给不同的代理,每个代理都有自己的工具,约束和职责。在本文中,我们将研究如何构建一个三个代理系统(研究,写作和审查),每个代理都处理在Internet上创建简洁历史报告的特定部分。我们还将确保系统不会陷入搜索循环,这可能会浪费时间和学分。
学习目标> > data Science Blogathon的一部分。 内容表 语言模型(LLM) - OpenAI GPT-4
>工具是代理可以打电话以在其语言建模之外执行操作的功能。典型的工具包括:
############################################################################### # 1. INSTALLATION ############################################################################### # Make sure you have the following installed: # pip install llama-index langchain duckduckgo-search ############################################################################### # 2. IMPORTS ############################################################################### %pip install llama-index langchain duckduckgo-search from llama_index.llms.openai import OpenAI # For DuckDuckGo search via LangChain from langchain.utilities import DuckDuckGoSearchAPIWrapper # llama-index workflow classes from llama_index.core.workflow import Context from llama_index.core.agent.workflow import ( FunctionAgent, AgentWorkflow, AgentInput, AgentOutput, ToolCall, ToolCallResult, AgentStream ) import asyncio ############################################################################### # 3. CREATE LLM ############################################################################### # Replace "sk-..." with your actual OpenAI API key llm = OpenAI(model="gpt-4", api_key="OPENAI_API_KEY")
> functionagent
的实例。关键字段包括:############################################################################### # 4. DEFINE DUCKDUCKGO SEARCH TOOL WITH SAFEGUARDS ############################################################################### # We wrap LangChain's DuckDuckGoSearchAPIWrapper with our own logic # to prevent repeated or excessive searches. duckduckgo = DuckDuckGoSearchAPIWrapper() MAX_SEARCH_CALLS = 2 search_call_count = 0 past_queries = set() async def safe_duckduckgo_search(query: str) -> str: """ A DuckDuckGo-based search function that: 1) Prevents more than MAX_SEARCH_CALLS total searches. 2) Skips duplicate queries. """ global search_call_count, past_queries # Check for duplicate queries if query in past_queries: return f"Already searched for '{query}'. Avoiding duplicate search." # Check if we've reached the max search calls if search_call_count >= MAX_SEARCH_CALLS: return "Search limit reached, no more searches allowed." # Otherwise, perform the search search_call_count += 1 past_queries.add(query) # DuckDuckGoSearchAPIWrapper.run(...) is synchronous, but we have an async signature result = duckduckgo.run(query) return str(result) ############################################################################### # 5. OTHER TOOL FUNCTIONS: record_notes, write_report, review_report ############################################################################### async def record_notes(ctx: Context, notes: str, notes_title: str) -> str: """Store research notes under a given title in the shared context.""" current_state = await ctx.get("state") if "research_notes" not in current_state: current_state["research_notes"] = {} current_state["research_notes"][notes_title] = notes await ctx.set("state", current_state) return "Notes recorded." async def write_report(ctx: Context, report_content: str) -> str: """Write a report in markdown, storing it in the shared context.""" current_state = await ctx.get("state") current_state["report_content"] = report_content await ctx.set("state", current_state) return "Report written." async def review_report(ctx: Context, review: str) -> str: """Review the report and store feedback in the shared context.""" current_state = await ctx.get("state") current_state["review"] = review await ctx.set("state", current_state) return "Report reviewed."
############################################################################### # 1. INSTALLATION ############################################################################### # Make sure you have the following installed: # pip install llama-index langchain duckduckgo-search ############################################################################### # 2. IMPORTS ############################################################################### %pip install llama-index langchain duckduckgo-search from llama_index.llms.openai import OpenAI # For DuckDuckGo search via LangChain from langchain.utilities import DuckDuckGoSearchAPIWrapper # llama-index workflow classes from llama_index.core.workflow import Context from llama_index.core.agent.workflow import ( FunctionAgent, AgentWorkflow, AgentInput, AgentOutput, ToolCall, ToolCallResult, AgentStream ) import asyncio ############################################################################### # 3. CREATE LLM ############################################################################### # Replace "sk-..." with your actual OpenAI API key llm = OpenAI(model="gpt-4", api_key="OPENAI_API_KEY")
:
运行工作流程
############################################################################### # 4. DEFINE DUCKDUCKGO SEARCH TOOL WITH SAFEGUARDS ############################################################################### # We wrap LangChain's DuckDuckGoSearchAPIWrapper with our own logic # to prevent repeated or excessive searches. duckduckgo = DuckDuckGoSearchAPIWrapper() MAX_SEARCH_CALLS = 2 search_call_count = 0 past_queries = set() async def safe_duckduckgo_search(query: str) -> str: """ A DuckDuckGo-based search function that: 1) Prevents more than MAX_SEARCH_CALLS total searches. 2) Skips duplicate queries. """ global search_call_count, past_queries # Check for duplicate queries if query in past_queries: return f"Already searched for '{query}'. Avoiding duplicate search." # Check if we've reached the max search calls if search_call_count >= MAX_SEARCH_CALLS: return "Search limit reached, no more searches allowed." # Otherwise, perform the search search_call_count += 1 past_queries.add(query) # DuckDuckGoSearchAPIWrapper.run(...) is synchronous, but we have an async signature result = duckduckgo.run(query) return str(result) ############################################################################### # 5. OTHER TOOL FUNCTIONS: record_notes, write_report, review_report ############################################################################### async def record_notes(ctx: Context, notes: str, notes_title: str) -> str: """Store research notes under a given title in the shared context.""" current_state = await ctx.get("state") if "research_notes" not in current_state: current_state["research_notes"] = {} current_state["research_notes"][notes_title] = notes await ctx.set("state", current_state) return "Notes recorded." async def write_report(ctx: Context, report_content: str) -> str: """Write a report in markdown, storing it in the shared context.""" current_state = await ctx.get("state") current_state["report_content"] = report_content await ctx.set("state", current_state) return "Report written." async def review_report(ctx: Context, review: str) -> str: """Review the report and store feedback in the shared context.""" current_state = await ctx.get("state") current_state["review"] = review await ctx.set("state", current_state) return "Report reviewed."
############################################################################### # 1. INSTALLATION ############################################################################### # Make sure you have the following installed: # pip install llama-index langchain duckduckgo-search ############################################################################### # 2. IMPORTS ############################################################################### %pip install llama-index langchain duckduckgo-search from llama_index.llms.openai import OpenAI # For DuckDuckGo search via LangChain from langchain.utilities import DuckDuckGoSearchAPIWrapper # llama-index workflow classes from llama_index.core.workflow import Context from llama_index.core.agent.workflow import ( FunctionAgent, AgentWorkflow, AgentInput, AgentOutput, ToolCall, ToolCallResult, AgentStream ) import asyncio ############################################################################### # 3. CREATE LLM ############################################################################### # Replace "sk-..." with your actual OpenAI API key llm = OpenAI(model="gpt-4", api_key="OPENAI_API_KEY")
>工作流完成后,我们提取最终状态,其中包含生成的报告。印刷报告内容,然后是评论代理的任何审核反馈。这样可以确保输出完成,并在必要时可以进一步完善。
>############################################################################### # 4. DEFINE DUCKDUCKGO SEARCH TOOL WITH SAFEGUARDS ############################################################################### # We wrap LangChain's DuckDuckGoSearchAPIWrapper with our own logic # to prevent repeated or excessive searches. duckduckgo = DuckDuckGoSearchAPIWrapper() MAX_SEARCH_CALLS = 2 search_call_count = 0 past_queries = set() async def safe_duckduckgo_search(query: str) -> str: """ A DuckDuckGo-based search function that: 1) Prevents more than MAX_SEARCH_CALLS total searches. 2) Skips duplicate queries. """ global search_call_count, past_queries # Check for duplicate queries if query in past_queries: return f"Already searched for '{query}'. Avoiding duplicate search." # Check if we've reached the max search calls if search_call_count >= MAX_SEARCH_CALLS: return "Search limit reached, no more searches allowed." # Otherwise, perform the search search_call_count += 1 past_queries.add(query) # DuckDuckGoSearchAPIWrapper.run(...) is synchronous, but we have an async signature result = duckduckgo.run(query) return str(result) ############################################################################### # 5. OTHER TOOL FUNCTIONS: record_notes, write_report, review_report ############################################################################### async def record_notes(ctx: Context, notes: str, notes_title: str) -> str: """Store research notes under a given title in the shared context.""" current_state = await ctx.get("state") if "research_notes" not in current_state: current_state["research_notes"] = {} current_state["research_notes"][notes_title] = notes await ctx.set("state", current_state) return "Notes recorded." async def write_report(ctx: Context, report_content: str) -> str: """Write a report in markdown, storing it in the shared context.""" current_state = await ctx.get("state") current_state["report_content"] = report_content await ctx.set("state", current_state) return "Report written." async def review_report(ctx: Context, review: str) -> str: """Review the report and store feedback in the shared context.""" current_state = await ctx.get("state") current_state["review"] = review await ctx.set("state", current_state) return "Report reviewed."
使用Web搜索工具时,LLM可能会“混淆”并反复调用搜索功能。这可能导致不必要的成本或时间消耗。为了防止这种情况,我们使用了两种机制:
如果满足了任何一个条件(最大搜索或重复查询),我们的
研究
>从共享上下文中读取“ research_notes”。
评估内容。
最终输出存储在
final_state [“ report_content”]。结论 >通过将工作流程分为不同的代理,以获取
> search和>评论>,您可以创建一个功能强大的模块化系统,该系统: >收集相关信息(以一种受控的方式,防止搜索过多)
产生结构化的高质量输出 Q4。我可以更改提示以适应此工作流程的其他主题或样式吗?绝对地。您可以编辑每个代理的System_prompt,以根据所需的域或写作方式量身定制说明。例如,您可以指示写入列表,叙述性论文或技术摘要。
>本文所示的媒体不归Analytics Vidhya拥有,并由作者的酌情决定使用。
以上是LlamainDex进行研究和写作的多代理工作流程的详细内容。更多信息请关注PHP中文网其他相关文章!