mirror of
https://github.com/run-llama/multi-agents-workflow.git
synced 2026-07-20 00:54:10 -04:00
add roles and better output
This commit is contained in:
+27
-25
@@ -9,30 +9,6 @@ from app.core.function_call import FunctionCallingAgent
|
||||
import textwrap
|
||||
|
||||
|
||||
def create_call_workflow_fn(agent: Workflow) -> FunctionTool:
|
||||
def call_workflow_fn(input: str) -> str:
|
||||
raise NotImplementedError
|
||||
|
||||
def info(prefix: str, text: str) -> None:
|
||||
truncated = textwrap.shorten(text, width=255, placeholder="...")
|
||||
print(f"{prefix}: '{truncated}'")
|
||||
|
||||
async def acall_workflow_fn(input: str) -> str:
|
||||
with PrintPrefix(f"[{agent.name}]"):
|
||||
info("Input", input)
|
||||
ret = await agent.run(input=input)
|
||||
response = str(ret["response"])
|
||||
info("Output", response)
|
||||
return response
|
||||
|
||||
return FunctionTool.from_defaults(
|
||||
fn=call_workflow_fn, # not necessary with https://github.com/run-llama/llama_index/pull/15638/files
|
||||
async_fn=acall_workflow_fn,
|
||||
name=f"call_{agent.name}",
|
||||
description=f"Use this tool to delegate a task to the agent {agent.name}",
|
||||
)
|
||||
|
||||
|
||||
class AgentCallingAgent(FunctionCallingAgent):
|
||||
def __init__(
|
||||
self,
|
||||
@@ -41,11 +17,37 @@ class AgentCallingAgent(FunctionCallingAgent):
|
||||
**kwargs: Any,
|
||||
) -> None:
|
||||
agents = agents or []
|
||||
tools = [create_call_workflow_fn(agent) for agent in agents]
|
||||
tools = [self.create_call_workflow_fn(agent) for agent in agents]
|
||||
super().__init__(*args, tools=tools, **kwargs)
|
||||
# call add_workflows so agents will get detected by llama agents automatically
|
||||
self.add_workflows(**{agent.name: agent for agent in agents})
|
||||
|
||||
def create_call_workflow_fn(self, agent: Workflow) -> FunctionTool:
|
||||
def call_workflow_fn(input: str) -> str:
|
||||
raise NotImplementedError
|
||||
|
||||
def info(prefix: str, text: str) -> None:
|
||||
truncated = textwrap.shorten(text, width=255, placeholder="...")
|
||||
print(f"{prefix}: '{truncated}'")
|
||||
|
||||
async def acall_workflow_fn(input: str) -> str:
|
||||
info(f"[{self.name}->{agent.name}]", input)
|
||||
with PrintPrefix(f"[{agent.name}]"):
|
||||
ret = await agent.run(input=input)
|
||||
response = str(ret["response"])
|
||||
info(f"[{self.name}<-{agent.name}]", response)
|
||||
return response
|
||||
|
||||
return FunctionTool.from_defaults(
|
||||
fn=call_workflow_fn, # not necessary with https://github.com/run-llama/llama_index/pull/15638/files
|
||||
async_fn=acall_workflow_fn,
|
||||
name=f"call_{agent.name}",
|
||||
description=(
|
||||
f"Use this tool to delegate a sub task to the agent {agent.name}."
|
||||
+ (f" The agent is an expert in {agent.role}." if agent.role else "")
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
class AgentOrchestrator(AgentCallingAgent):
|
||||
def __init__(
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
from typing import Any, List
|
||||
from typing import Any, List, Optional
|
||||
|
||||
from llama_index.core.llms.function_calling import FunctionCallingLLM
|
||||
from llama_index.core.memory import ChatMemoryBuffer
|
||||
@@ -33,11 +33,13 @@ class FunctionCallingAgent(Workflow):
|
||||
verbose: bool = False,
|
||||
timeout: float = 360.0,
|
||||
name: str,
|
||||
role: Optional[str] = None,
|
||||
**kwargs: Any,
|
||||
) -> None:
|
||||
super().__init__(*args, verbose=verbose, timeout=timeout, **kwargs)
|
||||
self.tools = tools or []
|
||||
self.name = name
|
||||
self.role = role
|
||||
|
||||
if llm is None:
|
||||
llm = Settings.llm
|
||||
|
||||
@@ -38,6 +38,7 @@ def create_choreography(researcher, reviewer):
|
||||
return AgentCallingAgent(
|
||||
name="writer",
|
||||
agents=[researcher, reviewer],
|
||||
role="expert in writing blog posts",
|
||||
system_prompt="""You are an expert in writing blog posts. You are given a task to write a blog post. Before starting to write the post, consult the researcher agent to get the information you need. Don't make up any information yourself.
|
||||
After creating a draft for the post, send it to the reviewer agent to receive some feedback and make sure to incorporate the feedback from the reviewer.
|
||||
You can consult the reviewer and researcher multiple times. Only finish the task once the reviewer is satisfied.""",
|
||||
@@ -47,6 +48,7 @@ def create_choreography(researcher, reviewer):
|
||||
def create_orchestrator(researcher, reviewer):
|
||||
writer = FunctionCallingAgent(
|
||||
name="writer",
|
||||
role="expert in writing blog posts",
|
||||
system_prompt="""You are an expert in writing blog posts. You are given a task to write a blog post. Don't make up any information yourself. If you don't have the necessary information to write a blog post, reply "I need information about the topic to write the blog post". If you have all the information needed, write the blog post.""",
|
||||
)
|
||||
return AgentOrchestrator(
|
||||
@@ -58,10 +60,12 @@ async def main():
|
||||
researcher = FunctionCallingAgent(
|
||||
name="researcher",
|
||||
tools=[get_query_engine_tool()],
|
||||
role="expert in retrieving any unknown content",
|
||||
system_prompt="You are a researcher agent. You are given a researching task. You must use your tools to complete the research.",
|
||||
)
|
||||
reviewer = FunctionCallingAgent(
|
||||
name="reviewer",
|
||||
role="expert in reviewing blog posts",
|
||||
system_prompt="You are an expert in reviewing blog posts. You are given a task to review a blog post. Review the post for logical inconsistencies, ask critical questions, and provide suggestions for improvement. Furthermore, proofread the post for grammar and spelling errors. If the post is good, you can say 'The post is good.'",
|
||||
)
|
||||
# agent = create_choreography(researcher, reviewer)
|
||||
|
||||
Reference in New Issue
Block a user