classDiagram
class BaseAgent
class BaseAgentRunner
BaseAgent <|-- BaseAgentRunner
class AgentRunner
class BaseAgentWorker
class ReActAgent
class ReActAgentWorker
BaseAgentRunner<|-- AgentRunner
AgentRunner<|-- ReActAgent
ReActAgent<-- ReActAgentWorker
BaseAgentWorker <|-- ReActAgentWorker
class StructuredPlannerAgent
class BasePlanningAgentRunner
BasePlanningAgentRunner <|-- StructuredPlannerAgent
StructuredPlannerAgent<-- BaseAgentWorker
AgentRunner<|-- BasePlanningAgentRunner
class FunctionCallingAgent
AgentRunner <|-- FunctionCallingAgent
class FunctionCallingAgentWorker
FunctionCallingAgent <-- FunctionCallingAgentWorker
BaseAgentWorker <| -- FunctionCallingAgentWorker
from llama_index.core import Settings from llama_index.llms.ollama import Ollama from llama_index.embeddings.ollama import OllamaEmbedding base_url='http://localhost:11434' llm = Ollama(model="qwen2.5:latest", request_timeout=360.0,base_url=base_url) Settings.llm = llm Settings.embed_model = OllamaEmbedding(model_name="quentinz/bge-large-zh-v1.5:latest",base_url=base_url)
from llama_index.core.tools import FunctionTool defmultiply(a: float, b: float) -> float: """Multiply two numbers and returns the product""" return a * b multiply_tool = FunctionTool.from_defaults(fn=multiply) defadd(a: float, b: float) -> float: """Add two numbers and returns the sum""" return a + b add_tool = FunctionTool.from_defaults(fn=add)
FunctionCallingAgent 与 ReActAgent
1 2 3 4
from llama_index.core.agent import FunctionCallingAgent function_calling_agent=FunctionCallingAgent.from_tools(tools=[multiply_tool, add_tool],verbose=True) response = function_calling_agent.chat("计算结果,1000+157*2?") print(response)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
> Running step f 1466 f 93-b 140-4 f 58-b 800-b 7221 e 1 fe 5 cd. Step input: 计算结果,1000+157*2? Added user message to memory: 计算结果,1000+157*2? === Calling Function === Calling function: multiply with args: {"a": 157, "b": 2} === Function Output === 314 > Running step 4 a 7 cdcf 8-97 b 5-4 e 1 b-9387-62734 c 68 de 34. Step input: None === Calling Function === Calling function: add with args: {"a": 1000, "b": 314} === Function Output === 1314 > Running step 600 c 57 bf-c 783-49 fc-be 90-f 402 cd 35 e 78 a. Step input: None === LLM Response === 计算结果是 \( 1000 + 157 \times 2 = 1314 \)。 计算结果是 \( 1000 + 157 \times 2 = 1314 \)。
> Running step 13973598-2 e 38-4 cc 3-ba 70-0897 d 09 bb 55 c. Step input: 计算结果,1000+157*2? Thought: The current language of the user is: Chinese. I need to use a tool to help me answer the question. Action: multiply Action Input: {'a': 157, 'b': 2} Observation: 314 > Running step eb 577013-9 af 9-4864-8516-ca 97 b 24 d 288 f. Step input: None Thought: I can now perform the addition using the result from the multiplication. Action: add Action Input: {'a': 1000, 'b': 314} Observation: 1314 > Running step e 75 c 52 b 9-109 a-4 fdc-b 555-6159 e 9 c 3 fb 5 c. Step input: None Thought: I can answer without using any more tools. I'll use the user's language to answer Answer: 计算结果是 1314。 计算结果是 1314。
1 2 3 4 5 6 7 8 9 10 11 12 13
task = self.create_task(message) result_output = None dispatcher.event(AgentChatWithStepStartEvent(user_msg=message)) whileTrue: # pass step queue in as argument, assume step executor is stateless cur_step_output = self._run_step( task.task_id, mode=mode, tool_choice=tool_choice ) if cur_step_output.is_last: result_output = cur_step_output break # ensure tool_choice does not cause endless loops tool_choice = "auto"
Thought: The current language of the user is: (user's language). I need to use a tool to help me answer the question. Action: tool name (one of {tool_names}) if using a tool. Action Input: the input to the tool, in a JSON format representing the kwargs (e.g. {{"input": "hello world", "num_beams": 5}})
如果是最终结果,按照以下格式之一输出
1 2 3 4
Thought: I can answer without using any more tools. I'll use the user's language to answer Answer: [your answer here (In the same language as the user's question)] > Thought: I cannot answer the question with the provided tools. Answer: [your answer here (In the same language as the user's question)]
=== Initial plan === 计算乘法部分: 157 * 2 -> 314.0 Deps: [] 计算加法部分: 1000 + 314.0 -> 1314.0 Deps: ['计算乘法部分'] > Running step 3 cd 2 cc 1 c-0 f 45-4 fb 1-aad 7-d 28 b 4 c 821 f 2 c. Step input: 157 * 2 Added user message to memory: 157 * 2 === Calling Function === Calling function: multiply with args: {"a": 157, "b": 2} === Function Output === 314 > Running step 95 f 3 f 0 a 6-8 ba 7-4 dbc-9 e 86-f 33118 f 69 ad 5. Step input: None === LLM Response === The product of 157 and 2 is 314. === Refined plan === 计算加法部分: 1000 + 314.0 -> 1314.0 Deps: ['计算乘法部分'] 完成任务: -> 1314.0 Deps: ['计算加法部分'] > Running step abad 3 f 05-a 750-4 f 62-85 bd-28 db 75 fc 4 fb 6. Step input: 1000 + 314.0 Added user message to memory: 1000 + 314.0 === Calling Function === Calling function: add with args: {"a": 1000, "b": 314} === Function Output === 1314 > Running step 203 c 38 a 5-29 fd-4 bce-acac-5 c 3530 a 25 ed 3. Step input: None === LLM Response === The sum of 1000 and 314.0 is 1314.0. === Refined plan === 验证最终结果: -> 1314.0 Deps: ['计算加法部分'] > Running step bee 84 f 9 a-8 a 9 a-4555-94 e 9-e 6 ccf 2 deb 1 dc. Step input: Added user message to memory: === LLM Response === Great! If you have any other calculations or questions, feel free to ask! === Refined plan === 计算乘法部分: Math.Multiply (157, 2) -> succeeded Deps: [] 计算加法部分: Math.Add (1000, 314.0) -> succeeded Deps: ['计算乘法部分'] 验证最终结果: -> Great! If you have any other calculations or questions, feel free to ask! Deps: ['计算加法部分']
DEFAULT_INITIAL_PLAN_PROMPT = """\ Think step-by-step. Given a task and a set of tools, create a comprehesive, end-to-end plan to accomplish the task. Keep in mind not every task needs to be decomposed into multiple sub-tasks if it is simple enough. The plan should end with a sub-task that satisfies the overall task. The tools available are: {tools_str} Overall Task: {task} """
DEFAULT_PLAN_REFINE_PROMPT = """\ Think step-by-step. Given an overall task, a set of tools, and completed sub-tasks, update (if needed) the remaining sub-tasks so that the overall task can still be completed. The plan should end with a sub-task that satisfies the overall task. If the remaining sub-tasks are sufficient, you can skip this step. The tools available are: {tools_str} Overall Task: {task} Completed Sub-Tasks + Outputs: {completed_outputs} Remaining Sub-Tasks: {remaining_sub_tasks} """
创建初始任务和计划
以下根据 StructuredPlannerAgent 原理,使用低级 API 展示
1 2 3 4 5 6 7
plan_id = agent.create_plan("计算结果,1000+157*2?") print('------------'*3) plan = agent.state.plan_dict[plan_id] for sub_task in plan.sub_tasks: print(f"===== Sub Task {sub_task.name} =====") print("Expected output: ", sub_task.expected_output) print("Dependencies: ", sub_task.dependencies)
1 2 3 4 5 6 7 8 9 10 11 12 13 14
=== Initial plan === Step 1: Multiply 157 by 2: Multiply (157, 2) -> PENDING Deps: [] Step 2: Add the result of Step 1 to 1000: Add (1000, {result from Step 1}) -> PENDING Deps: ['Step 1'] ------------------------------------ ===== Sub Task Step 1: Multiply 157 by 2 ===== Expected output: PENDING Dependencies: [] ===== Sub Task Step 2: Add the result of Step 1 to 1000 ===== Expected output: PENDING Dependencies: ['Step 1']
执行第一组任务
1 2 3 4 5 6 7 8 9 10
# 获取下一步要执行的任务 next_tasks = agent.state.get_next_sub_tasks(plan_id) for sub_task in next_tasks: print(f"===== Sub Task {sub_task.name} =====") print("Expected output: ", sub_task.expected_output) print("Dependencies: ", sub_task.dependencies) # 执行任务 for sub_task in next_tasks: response = agent.run_task(sub_task.name) agent.mark_task_complete(plan_id, sub_task.name)
1 2 3 4 5 6 7 8 9 10 11 12
===== Sub Task Step 1: Multiply 157 by 2 ===== Expected output: PENDING Dependencies: [] > Running step 6008 e 40 b-5 e 57-471 f-9 a 0 d-94 c 422 c 5 c 9 be. Step input: multiply (157, 2) Added user message to memory: multiply (157, 2) === Calling Function === Calling function: multiply with args: {"a": 157, "b": 2} === Function Output === 314 > Running step dcf 22 d 0 b-c 100-4 a 88-83 ce-a 83 bbd 82 f 485. Step input: None === LLM Response === The product of 157 and 2 is 314.