Repository: antgroup/agentUniverse (language: python)

Issue:
compress pictures



Discussion / hints:

Fix patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 54bfed04..7ec09f51 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -24,6 +24,21 @@ Note - Additional remarks regarding the version.
 ***************************************************
 
 # Version Update History
+## [0.0.9] - 2024-06-14
+### Added
+- Added standard integration for Claude and Ollama LLM components
+- Added new Qwen embedding module
+- Added default agents for ReAct-Type and NL2API-Type
+
+### Note
+- Added new use cases
+  - RAG-Type Agent Examples: Legal Consultation Agent
+  - ReAct-Type Agent Examples: Python Code Generation and Execution Agent
+  - Multi-Agent: Discussion Group Based on Multi-Turn Multi-Agent Mode
+
+  For more details, please refer to the use case section in the user documentation.
+- Some code optimizations and documentation updates.
+
 ## [0.0.8] - 2024-06-06
 ### Added
 - Introduced a new monitor module
diff --git a/CHANGELOG_zh.md b/CHANGELOG_zh.md
index f938da24..600479be 100644
--- a/CHANGELOG_zh.md
+++ b/CHANGELOG_zh.md
@@ -24,6 +24,21 @@ Note - 对于版本的额外说明。
 ***************************************************
 
 # 版本更新记录
+## [0.0.9] - 2024-06-14
+### Added
+- LLM组件新增claude、ollama标准接入
+- 新增qwen embedding模块
+- 新增ReAct、nl2api默认agent
+
+### Note
+- 新增使用案例
+  - RAG类Agent案例-法律咨询Agent
+  - ReAct类Agent案例-Python代码生成与执行Agent
+  - 多智能体案例-基于多轮多Agent的讨论小组
+
+  详情请看用户文档案例部分。
+- 部分代码优化与文档更新
+
 ## [0.0.8] - 2024-06-06
 ### Added
 - 新增monitor模块
diff --git a/README.md b/README.md
index 977ad774..ee6656b2 100644
--- a/README.md
+++ b/README.md
@@ -5,7 +5,7 @@ Language version: [English](./README.md) | [中文](./README_zh.md) | [日本語
 ![](https://img.shields.io/badge/framework-agentUniverse-pink)
 ![](https://img.shields.io/badge/python-3.10%2B-blue?logo=Python)
 [![](https://img.shields.io/badge/%20license-Apache--2.0-yellow)](LICENSE)
-[![Static Badge](https://img.shields.io/badge/pypi-v0.0.8-blue?logo=pypi)](https://pypi.org/project/agentUniverse/)
+[![Static Badge](https://img.shields.io/badge/pypi-v0.0.9-blue?logo=pypi)](https://pypi.org/project/agentUniverse/)
 
 ![](docs/guidebook/_picture/logo_bar.jpg)
 ****************************************
@@ -44,6 +44,11 @@ We will show you how to:
 * Quickly serve the agent
 For details, please read [Quick Start](docs/guidebook/en/1_3_Quick_Start.md).
 
+## Use Cases
+[Legal Consultation Agent](./docs/guidebook/en/7_1_1_Legal_Consultation_Case.md)
+[Python Code Generation and Execution Agent](./docs/guidebook/en/7_1_1_Python_Auto_Runner.md)
+[Discussion Group Based on Multi-Turn Multi-Agent Mode](./docs/guidebook/en/6_2_1_Discussion_Group.md)
+
 ## Guidebook
 For more detailed information, please refer to the [Guidebook](docs/guidebook/en/0_index.md).
 
diff --git a/README_jp.md b/README_jp.md
index 967e2154..ec284e38 100644
--- a/README_jp.md
+++ b/README_jp.md
@@ -5,7 +5,7 @@
 ![](https://img.shields.io/badge/framework-agentUniverse-pink)
 ![](https://img.shields.io/badge/python-3.10%2B-blue?logo=Python)
 [![](https://img.shields.io/badge/%20license-Apache--2.0-yellow)](LICENSE)
-[![Static Badge](https://img.shields.io/badge/pypi-v0.0.8-blue?logo=pypi)](https://pypi.org/project/agentUniverse/)
+[![Static Badge](https://img.shields.io/badge/pypi-v0.0.9-blue?logo=pypi)](https://pypi.org/project/agentUniverse/)
 
 ![](docs/guidebook/_picture/logo_bar.jpg)
 ****************************************
@@ -43,6 +43,11 @@ pip install agentUniverse
 * エージェントを迅速に提供する
 詳細は、[クイックスタート](docs/guidebook/en/1_3_Quick_Start.md)をご覧ください。
 
+## 使用ケース
+[法律相談Agent](./docs/guidebook/en/7_1_1_Legal_Consultation_Case.md)
+[Pythonコード生成と実行Agent](./docs/guidebook/en/7_1_1_Python_Auto_Runner.md)
+[多回多Agentによるディスカッショングループ](./docs/guidebook/en/6_2_1_Discussion_Group.md)
+
 ## ガイドブック
 詳細情報については、[ガイドブック](docs/guidebook/en/0_index.md)を参照してください。
 
diff --git a/README_zh.md b/README_zh.md
index 17763f6e..d35db732 100644
--- a/README_zh.md
+++ b/README_zh.md
@@ -5,7 +5,7 @@
 ![](https://img.shields.io/badge/framework-agentUniverse-pink)
 ![](https://img.shields.io/badge/python-3.10%2B-blue?logo=Python)
 [![](https://img.shields.io/badge/%20license-Apache--2.0-yellow)](LICENSE)
-[![Static Badge](https://img.shields.io/badge/pypi-v0.0.8-blue?logo=pypi)](https://pypi.org/project/agentUniverse/)
+[![Static Badge](https://img.shields.io/badge/pypi-v0.0.9-blue?logo=pypi)](https://pypi.org/project/agentUniverse/)
 
 ![](docs/guidebook/_picture/logo_bar.jpg)
 ****************************************
@@ -47,6 +47,11 @@ pip install agentUniverse
 
 详情请阅读[快速开始](docs/guidebook/zh/1_3_%E5%BF%AB%E9%80%9F%E5%BC%80%E5%A7%8B.md) 。
 
+## 使用案例
+[法律咨询Agent](./docs/guidebook/zh/7_1_1_法律咨询案例.md)
+[Python代码生成与执行Agent](./docs/guidebook/zh/7_1_1_Python自动执行案例.md)
+[基于多轮多Agent的讨论小组](./docs/guidebook/zh/6_2_1_讨论组.md)
+
 ## 用户指南
 更多详细信息，请参阅[指南](docs/guidebook/zh/0_%E7%9B%AE%E5%BD%95.md) 。
 
diff --git a/agentuniverse/agent/action/knowledge/embedding/openai_embedding.py b/agentuniverse/agent/action/knowledge/embedding/openai_embedding.py
index 7fa660cc..f54bbd0d 100644
--- a/agentuniverse/agent/action/knowledge/embedding/openai_embedding.py
+++ b/agentuniverse/agent/action/knowledge/embedding/openai_embedding.py
@@ -5,6 +5,7 @@
 # @Author  : wangchongshi
 # @Email   : wangchongshi.wcs@antgroup.com
 # @FileName: openai_embedding.py
+
 from typing import List, Optional, Any
 
 from langchain_community.embeddings.openai import OpenAIEmbeddings
diff --git a/agentuniverse/agent/action/tool/tool.py b/agentuniverse/agent/action/tool/tool.py
index 2190592b..a005a41a 100644
--- a/agentuniverse/agent/action/tool/tool.py
+++ b/agentuniverse/agent/action/tool/tool.py
@@ -73,6 +73,24 @@ def input_check(self, kwargs: dict) -> None:
             if key not in kwargs.keys():
                 raise Exception(f'{self.get_instance_code()} - The input must include key: {key}.')
 
+    def langchain_run(self, *args, callbacks=None, **kwargs):
+        """The callable method that runs the tool."""
+        kwargs["callbacks"] = callbacks
+        tool_input = ToolInput(kwargs)
+        parse_result = self.parse_react_input(args[0])
+        for key in self.input_keys:
+            tool_input.add_data(key, parse_result[key])
+        return self.execute(tool_input)
+
+    def parse_react_input(self, input_str: str):
+        """
+            parse react string to you input
+            you can define your own logic here by override this function
+        """
+        return {
+            self.input_keys[0]: input_str
+        }
+
     @abstractmethod
     def execute(self, tool_input: ToolInput):
         raise NotImplementedError
@@ -80,7 +98,7 @@ def execute(self, tool_input: ToolInput):
     def as_langchain(self) -> LangchainTool:
         """Convert the agentUniverse(aU) tool class to the langchain tool class."""
         return LangchainTool(name=self.name,
-                             func=self.run,
+                             func=self.langchain_run,
                              description=self.description)
 
     def get_instance_code(self) -> str:
diff --git a/agentuniverse/agent/default/nl2api_agent/__init__.py b/agentuniverse/agent/default/nl2api_agent/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/agentuniverse/agent/default/nl2api_agent/default_cn_prompt.yaml b/agentuniverse/agent/default/nl2api_agent/default_cn_prompt.yaml
new file mode 100644
index 00000000..b2ec805f
--- /dev/null
+++ b/agentuniverse/agent/default/nl2api_agent/default_cn_prompt.yaml
@@ -0,0 +1,27 @@
+introduction: 你是一位精通工具选择ai助手。
+target: 你的目标是根据用户的问题选择出合适的工具。
+instruction: |
+  你需要根据问题和用户提供的工具，选择其中的一个或几个工具用来回答用户提出的问题。
+  你必须从多个角度、维度分析用户的问题，需要根据背景和问题，决定使用哪些工具可以回答用户问题。 
+  
+  您可以使用以下工具:
+  {tools}
+  
+  之前的对话: 
+  {chat_history}
+  
+  背景信息是: 
+  {background}
+  
+  回答必须是按照以下格式化的Json代码片段。
+  1. tools字段代表选择的几个工具的完整名称，列表格式。例如：[add, sub, mul, div]
+  2. thought字段代表选择工具的思考过程和原因。
+  ```{{
+    "tools": list,
+    "thought": string
+  }}```
+  
+  当前的问题：{input}
+metadata:
+  type: 'PROMPT'
+  version: 'default_nl2api_agent.cn'
diff --git a/agentuniverse/agent/default/nl2api_agent/default_en_prompt.yaml b/agentuniverse/agent/default/nl2api_agent/default_en_prompt.yaml
new file mode 100644
index 00000000..31f8b411
--- /dev/null
+++ b/agentuniverse/agent/default/nl2api_agent/default_en_prompt.yaml
@@ -0,0 +1,26 @@
+introduction: You are an AI assistant proficient in tool selection.
+target: Your goal is to select the appropriate tools based on the user's questions.
+instruction: |
+  Your task is to select one or several tools from those provided by the user, based on their question and the context, in order to answer the user's query.
+  You must analyze the user's problem from multiple angles and dimensions, taking into account the background and context of the question, and decide which tools can be used to answer the user's question.
+  You may use the following tools:  
+  {tools}
+
+  Previous conversation:
+  {chat_history}
+  
+  The background information is:
+  {background}
+  
+  The response must follow the format below as a formatted JSON code snippet.
+  1. The tools field represents the full names of the selected tools in a list format, such as:[add, sub, mul, div]
+  2. The thought field represents the thinking process and reasons behind the selection of tools.
+  ```{{
+    "tools": list,
+    "thought": string
+  }}```
+  
+  Question: {input}
+metadata:
+  type: 'PROMPT'
+  version: 'default_nl2api_agent.en'
diff --git a/agentuniverse/agent/default/nl2api_agent/nl2api_agent.py b/agentuniverse/agent/default/nl2api_agent/nl2api_agent.py
new file mode 100644
index 00000000..a88892a8
--- /dev/null
+++ b/agentuniverse/agent/default/nl2api_agent/nl2api_agent.py
@@ -0,0 +1,45 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+
+# @Time    : 2024/6/11 17:14
+# @Author  : weizjajj 
+# @Email   : weizhongjie.wzj@antgroup.com
+# @FileName: nl2api_agent.py
+
+from agentuniverse.agent.agent import Agent
+from agentuniverse.agent.input_object import InputObject
+
+
+class Nl2ApiAgent(Agent):
+    """ReAct Agent class."""
+
+    def input_keys(self) -> list[str]:
+        """Return the input keys of the Agent."""
+        return ['input']
+
+    def output_keys(self) -> list[str]:
+        """Return the output keys of the Agent."""
+        return ['output']
+
+    def parse_input(self, input_object: InputObject, agent_input: dict) -> dict:
+        """Agent parameter parsing.
+
+        Args:
+            input_object (InputObject): input parameters passed by the user.
+            agent_input (dict): agent input preparsed by the agent.
+        Returns:
+            dict: agent input parsed from `input_object` by the user.
+        """
+        agent_input['input'] = input_object.get_data('input')
+        self.agent_model.profile.setdefault('prompt_version', 'default_nl2api_agent.cn')
+        return agent_input
+
+    def parse_result(self, planner_result: dict) -> dict:
+        """Planner result parser.
+
+        Args:
+            planner_result(dict): Planner result
+        Returns:
+            dict: Agent result object.
+        """
+        return planner_result
diff --git a/agentuniverse/agent/default/nl2api_agent/nl2api_agent.yaml b/agentuniverse/agent/default/nl2api_agent/nl2api_agent.yaml
new file mode 100644
index 00000000..79245c65
--- /dev/null
+++ b/agentuniverse/agent/default/nl2api_agent/nl2api_agent.yaml
@@ -0,0 +1,17 @@
+info:
+  name: 'nl2api_agent'
+  description: 'nl2api agent'
+profile:
+  llm_model:
+    name: 'default_openai_llm'
+    model_name: 'gpt-4o'
+action:
+  tool:
+    - ''
+plan:
+  planner:
+    name: 'nl2api_planner'
+metadata:
+  type: 'AGENT'
+  module: 'agentuniverse.agent.default.nl2api_agent.nl2api_agent'
+  class: 'Nl2ApiAgent'
\ No newline at end of file
diff --git a/agentuniverse/agent/default/react_agent/__init__.py b/agentuniverse/agent/default/react_agent/__init__.py
new file mode 100644
index 00000000..89d328f4
--- /dev/null
+++ b/agentuniverse/agent/default/react_agent/__init__.py
@@ -0,0 +1,7 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+
+# @Time    : 2024/6/4 21:21
+# @Author  : wangchongshi
+# @Email   : wangchongshi.wcs@antgroup.com
+# @FileName: __init__.py.py
diff --git a/agentuniverse/agent/default/react_agent/default_cn_prompt.yaml b/agentuniverse/agent/default/react_agent/default_cn_prompt.yaml
new file mode 100644
index 00000000..df8d8659
--- /dev/null
+++ b/agentuniverse/agent/default/react_agent/default_cn_prompt.yaml
@@ -0,0 +1,35 @@
+introduction: 你是一位精通信息分析的ai助手。
+target: 你的目标是根据用户的问题以及给出的背景信息给出答案。
+instruction: |
+  你必须优先选择使用提供的工具回答用户提出的问题，若用户没有提供工具可以根据你的通识能力解决问题。
+  你在回答时问题必须使用中文回答。
+  你必须从多个角度、维度分析用户的问题，帮助用户获取最全面的信息，需要根据背景和问题，决定搜索哪些信息可以回答问题。 
+  请注意: 你在给出最终答案时需要从多角度给出更详细的原因，而不是一个简单的结论。
+  
+  您可以使用以下工具:
+  {tools}
+  
+  你的回答必须严格使用以下格式:
+  
+    Question: 您必须回答的问题
+    Thought: 你应该经常想想该怎么做
+    Action: 要采取的行动应该是 one of [{tool_names}]
+    Action Input: 行动的输入
+    Observation: 行动的结果
+    ... (Thought/Action/Action Input/Observation 的过程可以重复 N 次)
+    Thought: 我现在知道最终答案了
+    Final Answer: 原输入问题的最终答案
+  
+  之前的对话:
+  {chat_history}
+  
+  背景信息是:
+  {background}
+  
+  开始!
+  
+  Question: {input}
+  Thought:{agent_scratchpad}
+metadata:
+  type: 'PROMPT'
+  version: 'default_react_agent.cn'
diff --git a/agentuniverse/agent/default/react_agent/default_en_prompt.yaml b/agentuniverse/agent/default/react_agent/default_en_prompt.yaml
new file mode 100644
index 00000000..92137f90
--- /dev/null
+++ b/agentuniverse/agent/default/react_agent/default_en_prompt.yaml
@@ -0,0 +1,31 @@
+introduction: You are an AI assistant who is proficient in information analysis.
+target: Your goal is to give answers based on the user's question and the context given.
+instruction: |
+  Answer the following questions as best you can. You have access to the following tools:
+
+  {tools}
+
+  Use the following format:
+
+    Question: the input question you must answer
+    Thought: you should always think about what to do
+    Action: the action to take, should be one of [{tool_names}]
+    Action Input: the input to the action
+    Observation: the result of the action
+    ... (this Thought/Action/Action Input/Observation can repeat N times)
+    Thought: I now know the final answer
+    Final Answer: the final answer to the original input question
+  
+  Previous conversion:
+  {chat_history}
+  
+  Background:
+  {background}
+  
+  Begin!
+
+  Question: {input}
+  Thought:{agent_scratchpad}
+metadata:
+  type: 'PROMPT'
+  version: 'default_react_agent.en'
diff --git a/agentuniverse/agent/default/react_agent/react_agent.py b/agentuniverse/agent/default/react_agent/react_agent.py
new file mode 100644
index 00000000..f50e7057
--- /dev/null
+++ b/agentuniverse/agent/default/react_agent/react_agent.py
@@ -0,0 +1,44 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+
+# @Time    : 2024/5/31 21:22
+# @Author  : wangchongshi
+# @Email   : wangchongshi.wcs@antgroup.com
+# @FileName: react_agent.py
+from agentuniverse.agent.agent import Agent
+from agentuniverse.agent.input_object import InputObject
+
+
+class ReActAgent(Agent):
+    """ReAct Agent class."""
+
+    def input_keys(self) -> list[str]:
+        """Return the input keys of the Agent."""
+        return ['input']
+
+    def output_keys(self) -> list[str]:
+        """Return the output keys of the Agent."""
+        return ['output']
+
+    def parse_input(self, input_object: InputObject, agent_input: dict) -> dict:
+        """Agent parameter parsing.
+
+        Args:
+            input_object (InputObject): input parameters passed by the user.
+            agent_input (dict): agent input preparsed by the agent.
+        Returns:
+            dict: agent input parsed from `input_object` by the user.
+        """
+        agent_input['input'] = input_object.get_data('input')
+        self.agent_model.profile.setdefault('prompt_version', 'default_react_agent.cn')
+        return agent_input
+
+    def parse_result(self, planner_result: dict) -> dict:
+        """Planner result parser.
+
+        Args:
+            planner_result(dict): Planner result
+        Returns:
+            dict: Agent result object.
+        """
+        return planner_result
diff --git a/agentuniverse/agent/default/react_agent/react_agent.yaml b/agentuniverse/agent/default/react_agent/react_agent.yaml
new file mode 100644
index 00000000..48309fc5
--- /dev/null
+++ b/agentuniverse/agent/default/react_agent/react_agent.yaml
@@ -0,0 +1,17 @@
+info:
+  name: 'react_agent'
+  description: 'react agent'
+profile:
+  llm_model:
+    name: 'default_openai_llm'
+    model_name: 'gpt-4o'
+action:
+  tool:
+    - ''
+plan:
+  planner:
+    name: 'react_planner'
+metadata:
+  type: 'AGENT'
+  module: 'agentuniverse.agent.default.react_agent.react_agent'
+  class: 'ReActAgent'
\ No newline at end of file
diff --git a/agentuniverse/agent/plan/planner/executing_planner/executing_planner.py b/agentuniverse/agent/plan/planner/executing_planner/executing_planner.py
index 9d2a3db0..f792fea7 100644
--- a/agentuniverse/agent/plan/planner/executing_planner/executing_planner.py
+++ b/agentuniverse/agent/plan/planner/executing_planner/executing_planner.py
@@ -39,7 +39,7 @@ def invoke(self, agent_model: AgentModel, planner_input: dict, input_object: Inp
 
         memory: ChatMemory = self.handle_memory(agent_model, planner_input)
 
-        self.handle_all_actions(agent_model, planner_input, input_object)
+        self.run_all_actions(agent_model, planner_input, input_object)
 
         llm: LLM = self.handle_llm(agent_model)
 
diff --git a/agentuniverse/agent/plan/planner/nl2api_planner/__init__.py b/agentuniverse/agent/plan/planner/nl2api_planner/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/agentuniverse/agent/plan/planner/nl2api_planner/nl2api_planner.py b/agentuniverse/agent/plan/planner/nl2api_planner/nl2api_planner.py
new file mode 100644
index 00000000..55d7d8d7
--- /dev/null
+++ b/agentuniverse/agent/plan/planner/nl2api_planner/nl2api_planner.py
@@ -0,0 +1,111 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+# @Time    : 2024/3/18 10:50
+# @Author  : heji
+# @Email   : lc299034@antgroup.com
+# @FileName: expressing_planner.py
+"""Expressing planner module."""
+import asyncio
+
+from langchain_core.chat_history import InMemoryChatMessageHistory
+from langchain_core.output_parsers import JsonOutputParser
+from langchain_core.runnables.history import RunnableWithMessageHistory
+from langchain.tools import Tool as LangchainTool
+
+from agentuniverse.agent.action.tool.tool import Tool
+from agentuniverse.agent.action.tool.tool_manager import ToolManager
+from agentuniverse.agent.agent_model import AgentModel
+from agentuniverse.agent.input_object import InputObject
+from agentuniverse.agent.memory.chat_memory import ChatMemory
+from agentuniverse.agent.plan.planner.planner import Planner
+from agentuniverse.base.util.memory_util import generate_memories
+from agentuniverse.base.util.prompt_util import process_llm_token
+from agentuniverse.llm.llm import LLM
+from agentuniverse.prompt.prompt import Prompt
+from agentuniverse.prompt.prompt_manager import PromptManager
+from agentuniverse.prompt.prompt_model import AgentPromptModel
+
+
+class Nl2ApiPlanner(Planner):
+    """Expressing planner class."""
+
+    def invoke(self, agent_model: AgentModel, planner_input: dict, input_object: InputObject) -> dict:
+        """Invoke the planner.
+
+        Args:
+            agent_model (AgentModel): Agent model object.
+            planner_input (dict): Planner input object.
+            input_object (InputObject): The input parameters passed by the user.
+        Returns:
+            dict: The planner result.
+        """
+        memory: ChatMemory = self.handle_memory(agent_model, planner_input)
+
+        llm: LLM = self.handle_llm(agent_model)
+
+        prompt: Prompt = self.handle_prompt(agent_model, planner_input)
+
+        process_llm_token(llm, prompt.as_langchain(), agent_model.profile, planner_input)
+
+        chat_history = memory.as_langchain().chat_memory if memory else InMemoryChatMessageHistory()
+
+        chain_with_history = RunnableWithMessageHistory(
+            prompt.as_langchain() | llm.as_langchain(),
+            lambda session_id: chat_history,
+            history_messages_key="chat_history",
+            input_messages_key=self.input_key,
+        ) | JsonOutputParser()
+        res = asyncio.run(
+            chain_with_history.ainvoke(input=planner_input, config={"configurable": {"session_id": "unused"}}))
+        return {**planner_input, self.output_key: res, 'chat_history': generate_memories(chat_history)}
+
+    @staticmethod
+    def acquire_tools(action) -> list[LangchainTool]:
+        tool_names: list = action.get('tool') or list()
+        lc_tools: list[LangchainTool] = list()
+        for tool_name in tool_names:
+            tool: Tool = ToolManager().get_instance_obj(tool_name)
+            lc_tools.append(tool.as_langchain())
+        return lc_tools
+
+    def handle_prompt(self, agent_model: AgentModel, planner_input: dict) -> Prompt:
+        """
+        Prompt module processing.
+
+        Args:
+            agent_model (AgentModel): Agent model object.
+            planner_input (dict): Planner input object.
+        Returns:
+            ChatPrompt: The chat prompt instance.
+        """
+        tools = self.acquire_tools(action=agent_model.action)
+        lc_tools_str: str = ''
+        for lc_tool in tools:
+            lc_tools_str += "tool name:" + lc_tool.name + " " + "tool description:" + lc_tool.description + '\n'
+        lc_tool_names = "|".join([lc_tool.name for lc_tool in tools])
+        planner_input['tool_names'] = lc_tool_names
+        planner_input['tools'] = lc_tools_str
+        planner_input['agent_scratchpad'] = ''
+        #
+        profile: dict = agent_model.profile
+        #
+        profile_prompt_model: AgentPromptModel = AgentPromptModel(introduction=profile.get('introduction'),
+                                                                  target=profile.get('target'),
+                                                                  instruction=profile.get('instruction'))
+
+        # get the prompt by the prompt version
+        prompt_version: str = profile.get('prompt_version')
+        version_prompt: Prompt = PromptManager().get_instance_obj(prompt_version)
+
+        if version_prompt is None and not profile_prompt_model:
+            raise Exception("Either the `prompt_version` or `introduction & target & instruction`"
+                            " in agent profile configuration should be provided.")
+        if version_prompt:
+            version_prompt_model: AgentPromptModel = AgentPromptModel(
+                introduction=getattr(version_prompt, 'introduction', ''),
+                target=getattr(version_prompt, 'target', ''),
+                instruction=getattr(version_prompt, 'instruction', ''))
+            profile_prompt_model = profile_prompt_model + version_prompt_model
+
+        prompt = Prompt().build_prompt(profile_prompt_model, self.prompt_assemble_order)
+        return prompt
\ No newline at end of file
diff --git a/agentuniverse/agent/plan/planner/nl2api_planner/nl2api_planner.yaml b/agentuniverse/agent/plan/planner/nl2api_planner/nl2api_planner.yaml
new file mode 100644
index 00000000..1de5943f
--- /dev/null
+++ b/agentuniverse/agent/plan/planner/nl2api_planner/nl2api_planner.yaml
@@ -0,0 +1,6 @@
+name: 'nl2api_planner'
+description: 'nl2api planner'
+metadata:
+  type: 'PLANNER'
+  module: 'agentuniverse.agent.plan.planner.nl2api_planner.nl2api_planner'
+  class: 'Nl2ApiPlanner'
\ No newline at end of file
diff --git a/agentuniverse/agent/plan/planner/planner.py b/agentuniverse/agent/plan/planner/planner.py
index 7c9def6a..c30fd311 100644
--- a/agentuniverse/agent/plan/planner/planner.py
+++ b/agentuniverse/agent/plan/planner/planner.py
@@ -90,7 +90,7 @@ def handle_memory(self, agent_model: AgentModel, planner_input: dict) -> ChatMem
         memory.set_by_agent_model(**params)
         return memory
 
-    def handle_all_actions(self, agent_model: AgentModel, planner_input: dict, input_object: InputObject):
+    def run_all_actions(self, agent_model: AgentModel, planner_input: dict, input_object: InputObject):
         """Tool and knowledge processing.
 
         Args:
diff --git a/agentuniverse/agent/plan/planner/rag_planner/rag_planner.py b/agentuniverse/agent/plan/planner/rag_planner/rag_planner.py
index f95ea34d..4edb1f6a 100644
--- a/agentuniverse/agent/plan/planner/rag_planner/rag_planner.py
+++ b/agentuniverse/agent/plan/planner/rag_planner/rag_planner.py
@@ -40,7 +40,7 @@ def invoke(self, agent_model: AgentModel, planner_input: dict,
         """
         memory: ChatMemory = self.handle_memory(agent_model, planner_input)
 
-        self.handle_all_actions(agent_model, planner_input, input_object)
+        self.run_all_actions(agent_model, planner_input, input_object)
 
         llm: LLM = self.handle_llm(agent_model)
 
diff --git a/agentuniverse/agent/plan/planner/react_planner/__init__.py b/agentuniverse/agent/plan/planner/react_planner/__init__.py
new file mode 100644
index 00000000..233deb77
--- /dev/null
+++ b/agentuniverse/agent/plan/planner/react_planner/__init__.py
@@ -0,0 +1,7 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+
+# @Time    : 2024/6/4 21:00
+# @Author  : wangchongshi
+# @Email   : wangchongshi.wcs@antgroup.com
+# @FileName: __init__.py.py
diff --git a/agentuniverse/agent/plan/planner/react_planner/react_planner.py b/agentuniverse/agent/plan/planner/react_planner/react_planner.py
new file mode 100644
index 00000000..ef1f76f9
--- /dev/null
+++ b/agentuniverse/agent/plan/planner/react_planner/react_planner.py
@@ -0,0 +1,122 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+
+# @Time    : 2024/5/31 21:22
+# @Author  : wangchongshi
+# @Email   : wangchongshi.wcs@antgroup.com
+# @FileName: react_planner.py
+
+from langchain_core.chat_history import InMemoryChatMessageHistory
+from langchain.agents import AgentExecutor, create_react_agent
+from langchain.tools import Tool as LangchainTool
+from langchain_core.runnables import RunnableConfig
+
+from agentuniverse.agent.action.tool.tool import Tool
+from agentuniverse.agent.action.tool.tool_manager import ToolManager
+from agentuniverse.agent.agent_model import AgentModel
+from agentuniverse.agent.input_object import InputObject
+from agentuniverse.agent.memory.chat_memory import ChatMemory
+from agentuniverse.agent.plan.planner.planner import Planner
+from agentuniverse.agent.plan.planner.react_planner.stream_callback import StreamOutPutCallbackHandler
+from agentuniverse.base.util.prompt_util import process_llm_token
+from agentuniverse.llm.llm import LLM
+from agentuniverse.prompt.chat_prompt import ChatPrompt
+from agentuniverse.prompt.prompt import Prompt
+from agentuniverse.prompt.prompt_manager import PromptManager
+from agentuniverse.prompt.prompt_model import AgentPromptModel
+
+
+class ReActPlanner(Planner):
+    """ReAct planner class."""
+
+    tools: list[LangchainTool] = None
+
+    def invoke(self, agent_model: AgentModel, planner_input: dict,
+               input_object: InputObject) -> dict:
+        """Invoke the planner.
+
+        Args:
+            agent_model (AgentModel): Agent model object.
+            planner_input (dict): Planner input object.
+            input_object (InputObject): The input parameters passed by the user.
+        Returns:
+            dict: The planner result.
+        """
+
+        memory: ChatMemory = self.handle_memory(agent_model, planner_input)
+
+        llm: LLM = self.handle_llm(agent_model)
+
+        tools = self.acquire_tools(agent_model.action)
+
+        prompt: Prompt = self.handle_prompt(agent_model, planner_input)
+        process_llm_token(llm, prompt.as_langchain(), agent_model.profile, planner_input)
+        chat_history = memory.as_langchain().chat_memory if memory else InMemoryChatMessageHistory()
+
+        agent = create_react_agent(llm.as_langchain(), tools, prompt.as_langchain())
+        agent_executor = AgentExecutor(agent=agent, tools=tools,
+                                       verbose=True,
+                                       handle_parsing_errors=True,
+                                       max_iterations=agent_model.plan.get('planner').get("max_iterations", 15))
+
+        return agent_executor.invoke(input=planner_input, memory=memory.as_langchain() if memory else None,
+                                     chat_history=chat_history, config=self.get_run_config(input_object))
+
+    @staticmethod
+    def get_run_config(input_object: InputObject) -> RunnableConfig:
+        config = RunnableConfig()
+        callbacks = []
+        output_stream = input_object.get_data('output_stream')
+        callbacks.append(StreamOutPutCallbackHandler(output_stream))
+        config.setdefault("callbacks", callbacks)
+        return config
+
+    @staticmethod
+    def acquire_tools(action) -> list[LangchainTool]:
+        tool_names: list = action.get('tool') or list()
+        lc_tools: list[LangchainTool] = list()
+        for tool_name in tool_names:
+            tool: Tool = ToolManager().get_instance_obj(tool_name)
+            lc_tools.append(tool.as_langchain())
+        return lc_tools
+
+    def handle_prompt(self, agent_model: AgentModel, planner_input: dict) -> Prompt:
+        """Prompt module processing.
+
+        Args:
+            agent_model (AgentModel): Agent model object.
+            planner_input (dict): Planner input object.
+        Returns:
+            ChatPrompt: The chat prompt instance.
+        """
+        lc_tools_str: str = ''
+        tools = self.acquire_tools(agent_model.action)
+        for lc_tool in self.acquire_tools(agent_model.action):
+            lc_tools_str += "tool name:" + lc_tool.name + " " + "tool description:" + lc_tool.description + '\n'
+        lc_tool_names = "|".join([lc_tool.name for lc_tool in tools])
+        planner_input['tool_names'] = lc_tool_names
+        planner_input['tools'] = lc_tools_str
+        planner_input['agent_scratchpad'] = ''
+
+        profile: dict = agent_model.profile
+
+        profile_prompt_model: AgentPromptModel = AgentPromptModel(introduction=profile.get('introduction'),
+                                                                  target=profile.get('target'),
+                                                                  instruction=profile.get('instruction'))
+
+        # get the prompt by the prompt version
+        prompt_version: str = profile.get('prompt_version')
+        version_prompt: Prompt = PromptManager().get_instance_obj(prompt_version)
+
+        if version_prompt is None and not profile_prompt_model:
+            raise Exception("Either the `prompt_version` or `introduction & target & instruction`"
+                            " in agent profile configuration should be provided.")
+        if version_prompt:
+            version_prompt_model: AgentPromptModel = AgentPromptModel(
+                introduction=getattr(version_prompt, 'introduction', ''),
+                target=getattr(version_prompt, 'target', ''),
+                instruction=getattr(version_prompt, 'instruction', ''))
+            profile_prompt_model = profile_prompt_model + version_prompt_model
+
+        prompt = Prompt().build_prompt(profile_prompt_model, self.prompt_assemble_order)
+        return prompt
diff --git a/agentuniverse/agent/plan/planner/react_planner/react_planner.yaml b/agentuniverse/agent/plan/planner/react_planner/react_planner.yaml
new file mode 100644
index 00000000..8af5eefb
--- /dev/null
+++ b/agentuniverse/agent/plan/planner/react_planner/react_planner.yaml
@@ -0,0 +1,6 @@
+name: 'react_planner'
+description: 'react planner'
+metadata:
+  type: 'PLANNER'
+  module: 'agentuniverse.agent.plan.planner.react_planner.react_planner'
+  class: 'ReActPlanner'
\ No newline at end of file
diff --git a/agentuniverse/agent/plan/planner/react_planner/stream_callback.py b/agentuniverse/agent/plan/planner/react_planner/stream_callback.py
new file mode 100644
index 00000000..87ec6acd
--- /dev/null
+++ b/agentuniverse/agent/plan/planner/react_planner/stream_callback.py
@@ -0,0 +1,64 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+
+# @Time    : 2024/6/13 11:03
+# @Author  : weizjajj 
+# @Email   : weizhongjie.wzj@antgroup.com
+# @FileName: stream_callback.py
+
+import asyncio
+from typing import Optional, Dict, Any
+
+from langchain_core.agents import AgentAction, AgentFinish
+from langchain_core.callbacks import BaseCallbackHandler
+
+
+class StreamOutPutCallbackHandler(BaseCallbackHandler):
+    """Callback Handler that prints to std out."""
+
+    def __init__(self, queue_stream: asyncio.Queue, color: Optional[str] = None) -> None:
+        """Initialize callback handler."""
+        self.queueStream = queue_stream
+        self.color = color
+
+    def on_chain_start(
+            self, serialized: Dict[str, Any], inputs: Dict[str, Any], **kwargs: Any
+    ) -> None:
+        return
+
+    def on_chain_end(self, outputs: Dict[str, Any], **kwargs: Any) -> None:
+        """Print out that we finished a chain."""
+
+    def on_agent_action(
+            self, action: AgentAction, color: Optional[str] = None, **kwargs: Any
+    ) -> Any:
+        self.queueStream.put_nowait("Thought:"+action.log)
+
+    def on_tool_end(
+            self,
+            output: str,
+            color: Optional[str] = None,
+            observation_prefix: Optional[str] = None,
+            llm_prefix: Optional[str] = None,
+            **kwargs: Any,
+    ) -> None:
+        """If not the final action, print out observation."""
+        if observation_prefix is not None:
+            self.queueStream.put_nowait(observation_prefix + output)
+        else:
+            self.queueStream.put_nowait('Observation:'+output)
+
+    def on_text(
+            self,
+            text: str,
+            color: Optional[str] = None,
+            end: str = "",
+            **kwargs: Any,
+    ) -> None:
+        """Run when agent ends."""
+
+    def on_agent_finish(
+            self, finish: AgentFinish, color: Optional[str] = None, **kwargs: Any
+    ) -> None:
+        """Run on agent end."""
+        self.queueStream.put_nowait("Thought:" + finish.log + "\n")
diff --git a/agentuniverse/base/util/prompt_util.py b/agentuniverse/base/util/prompt_util.py
index ec6b2dcb..cc0b0612 100644
--- a/agentuniverse/base/util/prompt_util.py
+++ b/agentuniverse/base/util/prompt_util.py
@@ -163,6 +163,9 @@ def process_llm_token(agent_llm: LLM, lc_prompt_template, profile: dict, planner
     prompt_tokens: int = agent_llm.get_num_tokens(prompt)
 
     input_tokens = agent_llm.max_context_length() - agent_llm.max_tokens
+    if input_tokens <= 0:
+        raise Exception("The current output max tokens limit is greater than the context length of the LLM model, "
+                        "please adjust it by editing the `max_tokens` parameter in the llm yaml.")
 
     if prompt_tokens <= input_tokens:
         return
diff --git a/agentuniverse/llm/claude_langchain_instance.py b/agentuniverse/llm/claude_langchain_instance.py
new file mode 100644
index 00000000..e7876543
--- /dev/null
+++ b/agentuniverse/llm/claude_langchain_instance.py
@@ -0,0 +1,93 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+
+# @Time    : 2024/5/22 17:07
+# @Author  : weizjajj 
+# @Email   : weizhongjie.wzj@antgroup.com
+# @FileName: claude_langchain_instance.py
+
+import warnings
+from typing import List, Optional, Any
+
+from langchain_anthropic import ChatAnthropic
+from langchain_anthropic.chat_models import _tools_in_params
+from langchain_core.callbacks import CallbackManagerForLLMRun, AsyncCallbackManagerForLLMRun
+from langchain_core.language_models.chat_models import generate_from_stream, agenerate_from_stream
+from langchain_core.messages import BaseMessage, SystemMessage, HumanMessage
+from langchain_core.outputs import ChatResult
+
+from agentuniverse.llm.llm import LLM
+
+
+class ClaudeLangChainInstance(ChatAnthropic):
+    """
+    This class wraps the Claude API into a LangChain API.
+    """
+    llm: LLM = None
+
+    def __init__(self, llm: LLM):
+        init_params = {}
+        init_params['model'] = llm.model_name if llm.model_name else 'Claude-Instant-V1.3'
+        init_params['temperature'] = llm.temperature if llm.temperature else 0.7
+        init_params['default_request_timeout'] = llm.request_timeout
+        init_params['streaming'] = llm.streaming if llm.streaming else False
+        init_params['anthropic_api_key'] = llm.anthropic_api_key if llm.anthropic_api_key else 'blank'
+        init_params['max_tokens'] = llm.max_tokens
+        init_params['max_retries'] = llm.max_retries if llm.max_retries else 2
+        init_params['anthropic_api_url'] = llm.anthropic_api_url
+        init_params['streaming'] = llm.streaming
+        init_params['llm'] = llm
+        super().__init__(**init_params)
+
+    def _generate(
+            self,
+            messages: List[BaseMessage],
+            stop: Optional[List[str]] = None,
+            run_manager: Optional[CallbackManagerForLLMRun] = None,
+            **kwargs: Any,
+    ) -> ChatResult:
+        if len(messages) > 1 and isinstance(messages[1], SystemMessage):
+            messages[1] = HumanMessage(content=messages[1].content)
+        params = self._format_params(messages=messages, stop=stop, **kwargs)
+        if self.streaming:
+            if _tools_in_params(params):
+                warnings.warn(
+                    "stream: Tool use is not yet supported in streaming mode."
+                )
+            else:
+                stream_iter = self._stream(
+                    messages, stop=stop, run_manager=run_manager, **kwargs
+                )
+                return generate_from_stream(stream_iter)
+        if _tools_in_params(params):
+            data = self._client.beta.tools.messages.create(**params)
+        else:
+            data = self.llm.call(**params).raw
+        return self._format_output(data, **kwargs)
+
+    async def _agenerate(
+            self,
+            messages: List[BaseMessage],
+            stop: Optional[List[str]] = None,
+            run_manager: Optional[AsyncCallbackManagerForLLMRun] = None,
+            **kwargs: Any,
+    ) -> ChatResult:
+        if len(messages) > 1 and isinstance(messages[1], SystemMessage):
+            messages[1] = HumanMessage(content=messages[1].content)
+        params = self._format_params(messages=messages, stop=stop, **kwargs)
+        if self.streaming:
+            if _tools_in_params(params):
+                warnings.warn(
+                    "stream: Tool use is not yet supported in streaming mode."
+                )
+            else:
+                stream_iter = self._astream(
+                    messages, stop=stop, run_manager=run_manager, **kwargs
+                )
+                return await agenerate_from_stream(stream_iter)
+        if _tools_in_params(params):
+            data = await self._async_client.beta.tools.messages.create(**params)
+        else:
+            data = await self.llm.acall(**params)
+            data = data.raw
+        return self._format_output(data, **kwargs)
diff --git a/agentuniverse/llm/default/claude_llm.py b/agentuniverse/llm/default/claude_llm.py
new file mode 100644
index 00000000..bee1f820
--- /dev/null
+++ b/agentuniverse/llm/default/claude_llm.py
@@ -0,0 +1,154 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+
+# @Time    : 2024/5/21 17:49
+# @Author  : weizjajj 
+# @Email   : weizhongjie.wzj@antgroup.com
+# @FileName: claude_llm.py
+
+import asyncio
+from typing import Optional, Any, Union, Iterator, AsyncIterator
+
+import anthropic
+import httpx
+from langchain_core.language_models import BaseLanguageModel
+from pydantic import Field
+
+from agentuniverse.base.annotation.trace import trace_llm
+from agentuniverse.base.util.env_util import get_from_env
+from agentuniverse.llm.claude_langchain_instance import ClaudeLangChainInstance
+from agentuniverse.llm.llm import LLM
+from agentuniverse.llm.llm_output import LLMOutput
+
+ClaudeMAXCONTETNLENGTH = {
+    "claude-3-opus-20240229": 200000,
+    "claude-3-sonnet-20240229": 200000,
+    "claude-3-haiku-20240307": 200000,
+    "claude-2.1": 200000,
+    "claude-2.0": 100000,
+    "claude-instant-1.2": 100000
+}
+
+
+class ClaudeLLM(LLM):
+    """
+    This class implements an interface for interacting with the Anthropic Claude model.
+
+    Attribute:
+        anthropic_api_key (Optional[str]): The API key for the Anthropic API. Defaults to the value of the environment variable ANTHROPIC_API_KEY.
+        anthropic_api_url (Optional[str]): The URL for the Anthropic API. Defaults to the value of the environment variable ANTHROPIC_API_URL.
+        anthropic_proxy (Optional[str]): The proxy to use for the Anthropic API. Defaults to None.
+        connection_pool_limits (Optional[int]): The maximum number of connections to keep in a pool. Defaults to None.
+    """
+    anthropic_api_key: Optional[str] = Field(default_factory=lambda: get_from_env('ANTHROPIC_API_KEY'))
+    anthropic_api_url: Optional[str] = Field(default_factory=lambda: get_from_env('ANTHROPIC_API_URL'))
+    anthropic_proxy: Optional[str] = None
+    connection_pool_limits: Optional[int] = None
+
+    def _new_client(self):
+        client = anthropic.Anthropic(
+            api_key=self.anthropic_api_key,
+            base_url=self.anthropic_api_url,
+            timeout=self.request_timeout if self.request_timeout else 60,
+            max_retries=self.max_retries if self.max_retries else 2,
+            http_client=httpx.Client(proxy=self.anthropic_proxy) if self.anthropic_proxy else None,
+            connection_pool_limits=self.connection_pool_limits
+        )
+        return client
+
+    def _new_async_client(self):
+        client = anthropic.AsyncAnthropic(
+            api_key=self.anthropic_api_key,
+            base_url=self.anthropic_api_url,
+            timeout=self.request_timeout if self.request_timeout else 60,
+            max_retries=self.max_retries if self.max_retries else 2,
+            http_client=httpx.AsyncClient(proxy=self.anthropic_proxy) if self.anthropic_proxy else None,
+            connection_pool_limits=self.connection_pool_limits
+        )
+        return client
+    @trace_llm
+    def call(self, messages: list, **kwargs: Any) -> Union[LLMOutput, Iterator[LLMOutput]]:
+        """Run the Claude LLM.
+
+        Args:
+            messages (list): The messages to send to the LLM.
+            **kwargs: Arbitrary keyword arguments.
+        """
+        streaming = kwargs.pop("streaming") if "streaming" in kwargs else self.streaming
+        self.client = self._new_client()
+        chat_completion = self.client.messages.create(
+            messages=messages,
+            model=kwargs.pop('model', self.model_name),
+            temperature=kwargs.pop('temperature', self.temperature),
+            stream=kwargs.pop('stream', streaming),
+            max_tokens=kwargs.pop('max_tokens', self.max_tokens),
+            **kwargs,
+        )
+        if not streaming:
+            self.close()
+            return self.parse_result(chat_completion)
+        return self.generate_stream_result(chat_completion)
+
+    @trace_llm
+    async def acall(self, messages: list, **kwargs: Any) -> Union[LLMOutput, AsyncIterator[LLMOutput]]:
+        streaming = kwargs.pop("streaming") if "streaming" in kwargs else self.streaming
+        self.client = self._new_async_client()
+        chat_completion = await self.client.messages.create(
+            messages=messages,
+            model=kwargs.pop('model', self.model_name),
+            temperature=kwargs.pop('temperature', self.temperature),
+            stream=kwargs.pop('stream', streaming),
+            max_tokens=kwargs.pop('max_tokens', self.max_tokens),
+            **kwargs,
+        )
+        if not streaming:
+            await self.aclose()
+            return self.parse_result(chat_completion)
+        return self.agenerate_stream_result(chat_completion)
+
+    @staticmethod
+    def parse_result(data):
+        text = data.content[0].text
+        if not text:
+            return
+        return LLMOutput(text=text, raw=data)
+
+    def generate_stream_result(self, chat_completion: Iterator):
+        for chunk in chat_completion:
+            if chunk.type != 'content_block_delta':
+                continue
+            yield LLMOutput(text=chunk.delta.text, raw=chunk.model_dump())
+        self.close()
+
+    async def agenerate_stream_result(self, chat_completion: AsyncIterator):
+        async for chunk in chat_completion:
+            print(chunk)
+            if chunk.type != 'content_block_delta':
+                continue
+            yield LLMOutput(text=chunk.delta.text, raw=chunk.model_dump())
+        await self.aclose()
+
+    def as_langchain(self) -> BaseLanguageModel:
+        """
+        Convert this instance into a LangChain compatible object
+        """
+        return ClaudeLangChainInstance(self)
+
+    def get_num_tokens(self, text: str) -> int:
+        encode = self._new_client().count_tokens(text)
+        return encode
+
+    def max_context_length(self) -> int:
+        if super().max_context_length():
+            return super().max_context_length()
+        return ClaudeMAXCONTETNLENGTH[self.model_name]
+
+    def close(self):
+        """Close the client."""
+        if hasattr(self, 'client') and self.client:
+            self.client.close()
+
+    async def aclose(self):
+        """Async close the client."""
+        if hasattr(self, 'async_client') and self.async_client:
+            await self.async_client.aclose()
diff --git a/agentuniverse/llm/default/claude_llm.yaml b/agentuniverse/llm/default/claude_llm.yaml
new file mode 100644
index 00000000..31538a3a
--- /dev/null
+++ b/agentuniverse/llm/default/claude_llm.yaml
@@ -0,0 +1,8 @@
+name: 'default_claude_llm'
+description: 'default kimi llm with spi'
+model_name: 'claude-3-opus-20240229'
+max_tokens: 4096
+metadata:
+  type: 'LLM'
+  module: 'agentuniverse.llm.default.claude_llm'
+  class: 'ClaudeLLM'
\ No newline at end of file
diff --git a/agentuniverse/llm/default/default_ollama_llm.py b/agentuniverse/llm/default/default_ollama_llm.py
new file mode 100644
index 00000000..e8cec875
--- /dev/null
+++ b/agentuniverse/llm/default/default_ollama_llm.py
@@ -0,0 +1,100 @@
+import json
+from typing import Any, Union, AsyncIterator, Iterator, Optional, List, Sequence
+
+import tiktoken
+from langchain_core.language_models import BaseLanguageModel
+from ollama import Options
+from pydantic import Field
+
+from agentuniverse.base.annotation.trace import trace_llm
+from agentuniverse.base.config.component_configer.configers.llm_configer import LLMConfiger
+from agentuniverse.base.util.env_util import get_from_env
+from agentuniverse.llm.llm import LLM
+from agentuniverse.llm.llm_output import LLMOutput
+from agentuniverse.llm.ollama_langchain_instance import OllamaLangchainInstance
+
+
+class OllamaLLM(LLM):
+    base_url: Optional[str] = Field(
+        default_factory=lambda: get_from_env("OLLAMA_BASE_URL") if get_from_env(
+            "OLLAMA_BASE_URL") else "http://localhost:11434")
+    """Base url the model is hosted under."""
+
+    streaming: bool = True
+
+    def _new_client(self):
+        if self.client:
+            return self.client
+        from ollama import Client
+        return Client(
+            host=self.base_url,
+        )
+
+    def _new_async_client(self):
+        if self.async_client:
+            return self.async_client
+        from ollama import AsyncClient
+        return AsyncClient(
+            host=self.base_url,
+        )
+
+    def _options(self):
+        return Options(**{
+            "num_ctx": self.max_context_length(),
+            "num_predict": self.max_tokens,
+            "temperature": self.temperature,
+            "timeout": self.request_timeout,
+            **(self.ext_info if self.ext_info else {}),
+        })
+
+    @trace_llm
+    def call(self, messages, stop=None, **kwargs) -> Union[LLMOutput, Iterator[LLMOutput]]:
+        should_stream = kwargs.pop("stream", self.streaming)
+        client = self._new_client()
+        options = self._options()
+        options.setdefault("stop", stop)
+        res = client.chat(model=self.model_name, messages=messages, options=options, stream=should_stream)
+        if should_stream:
+            return self.generate_result(res)
+        else:
+            return LLMOutput(text=res.get("message").get('content'), raw=json.dumps(res))
+
+    @trace_llm
+    async def acall(self, messages, stop=None, **kwargs) -> Union[LLMOutput, AsyncIterator[LLMOutput]]:
+        client = self._new_async_client()
+        should_stream = kwargs.pop("stream", self.streaming)
+        options = self._options()
+        options.setdefault("stop", stop)
+        res = await client.chat(model=self.model_name, messages=messages, options=options, stream=should_stream)
+        if not should_stream:
+            return LLMOutput(text=res.get("message").get('content'), raw=json.dumps(res))
+        if should_stream:
+            return self.agenerate_result(res)
+
+    def generate_result(self, data):
+        for line in data:
+            yield LLMOutput(text=line.get("message").get('content'), raw=json.dumps(line))
+
+    async def agenerate_result(self, data):
+        async for line in data:
+            yield LLMOutput(text=line.get("message").get('content'), raw=json.dumps(line))
+
+    def as_langchain(self) -> BaseLanguageModel:
+        return OllamaLangchainInstance(
+            self
+        )
+
+    def initialize_by_component_configer(self, component_configer: LLMConfiger) -> 'LLM':
+        super().initialize_by_component_configer(component_configer)
+        if 'base_url' in component_configer.configer.value:
+            self.base_url = component_configer.configer.value['base_url']
+        if 'max_context_length' in component_configer.configer.value:
+            self._max_context_length = component_configer.configer.value['max_context_length']
+        return self
+
+    def get_num_tokens(self, text: str) -> int:
+        try:
+            encoding = tiktoken.encoding_for_model(self.model_name)
+        except KeyError:
+            encoding = tiktoken.get_encoding("cl100k_base")
+        return len(encoding.encode(text))
diff --git a/agentuniverse/llm/default/default_ollama_llm.yaml b/agentuniverse/llm/default/default_ollama_llm.yaml
new file mode 100644
index 00000000..84b7a284
--- /dev/null
+++ b/agentuniverse/llm/default/default_ollama_llm.yaml
@@ -0,0 +1,9 @@
+name: 'default_ollama_llm'
+description: 'default openai llm with spi'
+model_name: 'qwen2:7b'
+max_tokens: 1000
+max_context_length: 32000
+metadata:
+  type: 'LLM'
+  module: 'agentuniverse.llm.default.default_ollama_llm'
+  class: 'OllamaLLM'
\ No newline at end of file
diff --git a/agentuniverse/llm/llm.py b/agentuniverse/llm/llm.py
index 736e7f67..53c4fd67 100644
--- a/agentuniverse/llm/llm.py
+++ b/agentuniverse/llm/llm.py
@@ -45,7 +45,7 @@ class LLM(ComponentBase):
     streaming: Optional[bool] = False
     ext_info: Optional[dict] = None
     tracing: Optional[bool] = None
-    __max_context_length: Optional[int] = None
+    _max_context_length: Optional[int] = None
 
     def __init__(self, **kwargs):
         """Initialize the llm."""
@@ -120,14 +120,14 @@ def set_by_agent_model(self, **kwargs) -> None:
         if 'streaming' in kwargs and kwargs['streaming']:
             self.streaming = kwargs['streaming']
         if 'max_context_length' in kwargs and kwargs['max_context_length']:
-            self.__max_context_length = kwargs['max_context_length']
+            self._max_context_length = kwargs['max_context_length']
 
     def max_context_length(self) -> int:
         """Max context length.
 
         The total length of input tokens and generated tokens is limited by the model's context length.
         """
-        return self.__max_context_length
+        return self._max_context_length
 
     @abstractmethod
     def get_num_tokens(self, text: str) -> int:
diff --git a/agentuniverse/llm/ollama_langchain_instance.py b/agentuniverse/llm/ollama_langchain_instance.py
new file mode 100644
index 00000000..845ffa64
--- /dev/null
+++ b/agentuniverse/llm/ollama_langchain_instance.py
@@ -0,0 +1,39 @@
+from typing import List, Optional, Iterator, Any, AsyncIterator
+
+from langchain_community.chat_models import ChatOllama
+from langchain_core.messages import BaseMessage
+
+from agentuniverse.llm.llm import LLM
+
+
+class OllamaLangchainInstance(ChatOllama):
+    llm: LLM = None
+
+    def __init__(self, llm: LLM):
+        super().__init__()
+        self.llm = llm
+        self.model = llm.model_name
+
+    def _create_chat_stream(
+            self,
+            messages: List[BaseMessage],
+            stop: Optional[List[str]] = None,
+            **kwargs: Any,
+    ) -> Iterator[str]:
+        data = self.llm.call(
+            messages=self._convert_messages_to_ollama_messages(messages), stop=stop, **kwargs
+        )
+        for llm_output in data:
+            yield llm_output.raw
+
+    async def _acreate_chat_stream(
+            self,
+            messages: List[BaseMessage],
+            stop: Optional[List[str]] = None,
+            **kwargs: Any,
+    ) -> AsyncIterator[str]:
+        data = await self.llm.acall(
+                messages=self._convert_messages_to_ollama_messages(messages), stop=stop, **kwargs
+        )
+        async for llm_output in data:
+            yield llm_output.raw
diff --git a/agentuniverse/llm/openai_style_langchain_instance.py b/agentuniverse/llm/openai_style_langchain_instance.py
index 8b9506ce..f17e01e8 100644
--- a/agentuniverse/llm/openai_style_langchain_instance.py
+++ b/agentuniverse/llm/openai_style_langchain_instance.py
@@ -6,11 +6,12 @@
 # @Email   : weizhongjie.wzj@antgroup.com
 # @FileName: langchain_openai_style_instance.py
 
-from typing import Any, List, Optional, AsyncIterator
+from typing import Any, List, Optional, AsyncIterator, Iterator
 
 from langchain.callbacks.manager import AsyncCallbackManagerForLLMRun, CallbackManagerForLLMRun
 from langchain.schema import BaseMessage, ChatResult
-from langchain_community.chat_models.openai import _convert_delta_to_message_chunk
+from langchain_community.chat_models.openai import _convert_delta_to_message_chunk, _create_retry_decorator
+from langchain_community.utils.openai import is_openai_v1
 from langchain_core.language_models.chat_models import generate_from_stream, agenerate_from_stream
 from langchain_core.messages import AIMessageChunk, get_buffer_string
 from langchain_core.outputs import ChatGenerationChunk
@@ -19,6 +20,25 @@
 from agentuniverse.llm.llm import LLM
 
 
+async def acompletion_with_retry(
+        llm: ChatOpenAI,
+        run_manager: Optional[AsyncCallbackManagerForLLMRun] = None,
+        **kwargs: Any,
+) -> Any:
+    """Use tenacity to retry the async completion call."""
+    if is_openai_v1():
+        return await llm.llm.acall(**kwargs)
+
+    retry_decorator = _create_retry_decorator(llm, run_manager=run_manager)
+
+    @retry_decorator
+    async def _completion_with_retry(**kwargs: Any) -> Any:
+        # Use OpenAI's async api https://github.com/openai/openai-python#async-api
+        return await llm.llm.acall(**kwargs)
+
+    return await _completion_with_retry(**kwargs)
+
+
 class LangchainOpenAIStyleInstance(ChatOpenAI):
     """Langchain OpenAI LLM wrapper."""
 
@@ -134,3 +154,88 @@ async def as_langchain_achunk(stream_iterator: AsyncIterator, run_manager=None)
     def get_num_tokens_from_messages(self, messages: List[BaseMessage]) -> int:
         messages_str = get_buffer_string(messages)
         return self.llm.get_num_tokens(messages_str)
+
+    def completion_with_retry(
+            self, run_manager: Optional[CallbackManagerForLLMRun] = None, **kwargs: Any
+    ) -> Any:
+        """Use tenacity to retry the completion call."""
+        if is_openai_v1():
+            return self.llm.call(**kwargs)
+
+        retry_decorator = _create_retry_decorator(self, run_manager=run_manager)
+
+        @retry_decorator
+        def _completion_with_retry(**kwargs: Any) -> Any:
+            return self.llm.call(**kwargs)
+
+        return _completion_with_retry(**kwargs)
+
+    def _stream(
+            self,
+            messages: List[BaseMessage],
+            stop: Optional[List[str]] = None,
+            run_manager: Optional[CallbackManagerForLLMRun] = None,
+            **kwargs: Any,
+    ) -> Iterator[ChatGenerationChunk]:
+        message_dicts, params = self._create_message_dicts(messages, stop)
+        params = {**params, **kwargs, "stream": True}
+
+        default_chunk_class = AIMessageChunk
+        for chunk in self.completion_with_retry(
+                messages=message_dicts, run_manager=run_manager, **params
+        ):
+            chunk = chunk.raw
+            if not isinstance(chunk, dict):
+                chunk = chunk.dict()
+            if len(chunk["choices"]) == 0:
+                continue
+            choice = chunk["choices"][0]
+            chunk = _convert_delta_to_message_chunk(
+                choice["delta"], default_chunk_class
+            )
+            finish_reason = choice.get("finish_reason")
+            generation_info = (
+                dict(finish_reason=finish_reason) if finish_reason is not None else None
+            )
+            default_chunk_class = chunk.__class__
+            cg_chunk = ChatGenerationChunk(
+                message=chunk, generation_info=generation_info
+            )
+            if run_manager:
+                run_manager.on_llm_new_token(cg_chunk.text, chunk=cg_chunk)
+            yield cg_chunk
+
+    async def _astream(
+            self,
+            messages: List[BaseMessage],
+            stop: Optional[List[str]] = None,
+            run_manager: Optional[AsyncCallbackManagerForLLMRun] = None,
+            **kwargs: Any,
+    ) -> AsyncIterator[ChatGenerationChunk]:
+        message_dicts, params = self._create_message_dicts(messages, stop)
+        params = {**params, **kwargs, "stream": True}
+
+        default_chunk_class = AIMessageChunk
+        async for chunk in await acompletion_with_retry(
+                self, messages=message_dicts, run_manager=run_manager, **params
+        ):
+            chunk = chunk.raw
+            if not isinstance(chunk, dict):
+                chunk = chunk.dict()
+            if len(chunk["choices"]) == 0:
+                continue
+            choice = chunk["choices"][0]
+            chunk = _convert_delta_to_message_chunk(
+                choice["delta"], default_chunk_class
+            )
+            finish_reason = choice.get("finish_reason")
+            generation_info = (
+                dict(finish_reason=finish_reason) if finish_reason is not None else None
+            )
+            default_chunk_class = chunk.__class__
+            cg_chunk = ChatGenerationChunk(
+                message=chunk, generation_info=generation_info
+            )
+            if run_manager:
+                await run_manager.on_llm_new_token(token=cg_chunk.text, chunk=cg_chunk)
+            yield cg_chunk
diff --git a/agentuniverse/llm/openai_style_llm.py b/agentuniverse/llm/openai_style_llm.py
index c4a84da4..2d5a3ea0 100644
--- a/agentuniverse/llm/openai_style_llm.py
+++ b/agentuniverse/llm/openai_style_llm.py
@@ -71,6 +71,8 @@ def call(self, messages: list, **kwargs: Any) -> Union[LLMOutput, Iterator[LLMOu
             **kwargs: Arbitrary keyword arguments.
         """
         streaming = kwargs.pop("streaming") if "streaming" in kwargs else self.streaming
+        if 'stream' in kwargs:
+            streaming = kwargs.pop('stream')
         self.client = self._new_client()
         client = self.client
         chat_completion = client.chat.completions.create(
diff --git a/docs/guidebook/_picture/agent_universe_framework_resize.jpg b/docs/guidebook/_picture/agent_universe_framework_resize.jpg
index 49b98171..85803339 100644
Binary files a/docs/guidebook/_picture/agent_universe_framework_resize.jpg and b/docs/guidebook/_picture/agent_universe_framework_resize.jpg differ
diff --git a/docs/guidebook/_picture/chinese_or_western_medicine.png b/docs/guidebook/_picture/chinese_or_western_medicine.png
new file mode 100644
index 00000000..e611f6ba
Binary files /dev/null and b/docs/guidebook/_picture/chinese_or_western_medicine.png differ
diff --git a/docs/guidebook/_picture/coca-cola_or_pepsi.png b/docs/guidebook/_picture/coca-cola_or_pepsi.png
new file mode 100644
index 00000000..619b98dc
Binary files /dev/null and b/docs/guidebook/_picture/coca-cola_or_pepsi.png differ
diff --git a/docs/guidebook/_picture/react_demo_step.png b/docs/guidebook/_picture/react_demo_step.png
new file mode 100644
index 00000000..84ad6909
Binary files /dev/null and b/docs/guidebook/_picture/react_demo_step.png differ
diff --git a/docs/guidebook/_picture/sweet_or_salted_zongzi.png b/docs/guidebook/_picture/sweet_or_salted_zongzi.png
new file mode 100644
index 00000000..76720c44
Binary files /dev/null and b/docs/guidebook/_picture/sweet_or_salted_zongzi.png differ
diff --git a/docs/guidebook/en/0_index.md b/docs/guidebook/en/0_index.md
index 36bb852b..6fa4e741 100644
--- a/docs/guidebook/en/0_index.md
+++ b/docs/guidebook/en/0_index.md
@@ -52,6 +52,8 @@
     * 3.1.2.3 [WenXin Usage Instructions](3_1_2_WenXin_LLM_Use.md)
     * 3.1.2.4 [Kimi Usage Instructions](3_1_2_Kimi_LLM_Use.md)
     * 3.1.2.5 [BaiChuan Usage Instructions](3_1_2_BaiChuan_LLM_Use.md)
+    * 3.1.2.6 [Claude Usage Instructions](3_1_2_Claude_LLM_Use.md)
+    * 3.1.2.7 [Ollama Usage Instructions](3_1_2_Ollama_LLM_Use.md)
   * 3.1.3 List of Tools
   * 3.1.4 List of Knowledge
   * 3.1.5 List of Memories
@@ -62,6 +64,7 @@
   * 3.2.2 Store
     * 3.2.2.1 [SQLDBWrapper](2_3_1_SQLDB_WRAPPER.md)
     * 3.2.2.2 [Milvus](3_3_1_Milvus.md)
+    * 3.2.2.3 [ChromaDB](3_3_2_ChromaDB.md)
   * 3.2.3 Msg
   * 3.2.4 Logging
     * 3.2.4.1 [Alibaba Cloud SLS](3_2_4_Alibaba_Cloud_SLS.md)
@@ -73,8 +76,15 @@
   * 5.1.1 [Docker Containerization Solution](5_1_1_Docker_Container_Deployment.md)
   * 5.1.2 [K8S Solution](5_1_2_K8S_Deployment.md)
 
-**6. Series of Articles**
+**6. Use Cases**
+* 6.1 RAG-Type Agent Examples
+  * 6.1.1 [Legal Consultation Agent](7_1_1_Legal_Consultation_Case.md)
+* 6.2 ReAct-Type Agent Examples
+  * 6.2.1 [Python Code Generation and Execution Agent](7_1_1_Python_Auto_Runner.md)
+* 6.3 [Discussion Group Based on Multi-Turn Multi-Agent Mode](6_2_1_Discussion_Group.md)
 
-**7. Frequently Asked Questions (FAQ)**
+**7. Series of Articles**
 
-**[8. Contact Us](6_1_Contact_Us.md)**
+**8. Frequently Asked Questions (FAQ)**
+
+**[9. Contact Us](6_1_Contact_Us.md)**
diff --git a/docs/guidebook/en/2_2_6_Planner_Define_And_Use.md b/docs/guidebook/en/2_2_6_Planner_Define_And_Use.md
index b67897fa..6979676b 100644
--- a/docs/guidebook/en/2_2_6_Planner_Define_And_Use.md
+++ b/docs/guidebook/en/2_2_6_Planner_Define_And_Use.md
@@ -112,7 +112,7 @@ class RagPlanner(Planner):
         """
         memory: ChatMemory = self.handle_memory(agent_model, planner_input)
 
-        self.handle_all_actions(agent_model, planner_input, input_object)
+        self.run_all_actions(agent_model, planner_input, input_object)
 
         llm: LLM = self.handle_llm(agent_model)
 
diff --git a/docs/guidebook/en/3_1_2_0_List_Of_LLMs.md b/docs/guidebook/en/3_1_2_0_List_Of_LLMs.md
index 5d5975eb..a56aa83f 100644
--- a/docs/guidebook/en/3_1_2_0_List_Of_LLMs.md
+++ b/docs/guidebook/en/3_1_2_0_List_Of_LLMs.md
@@ -8,7 +8,9 @@ The platform has currently integrated the following list of models; please refer
 | [WenXin](3_1_2_WenXin_LLM_Use.md)     |
 | [Kimi](3_1_2_Kimi_LLM_Use.md)         |
 | [BaiChuan](3_1_2_BaiChuan_LLM_Use.md) |
+| [Claude](3_1_2_Claude_LLM_Use.md)     |
+| [ollama](3_1_2_Ollama_LLM_Use.md)     |
 
 For LLM not included in the list, you can customize the integration of any LLM according to the steps provided in the [LLM definition](2_2_3_Tool_Create_And_Use.md).
 
-At the same time, we are adding the integration methods for common LLMs such as Claude, Gemini, ollama, Llama, ZhipuAI, etc. If you have used these LLMs in your projects and have created your own instances, we welcome you to submit a PR to become a contributor to agentUniverse.
\ No newline at end of file
+At the same time, we are adding the integration methods for common LLMs such as Gemini, Llama, ZhipuAI, etc. If you have used these LLMs in your projects and have created your own instances, we welcome you to submit a PR to become a contributor to agentUniverse.
\ No newline at end of file
diff --git a/docs/guidebook/en/3_1_2_Claude_LLM_Use.md b/docs/guidebook/en/3_1_2_Claude_LLM_Use.md
new file mode 100644
index 00000000..b18de2fd
--- /dev/null
+++ b/docs/guidebook/en/3_1_2_Claude_LLM_Use.md
@@ -0,0 +1,34 @@
+# Calude Usage
+## 1. Create the relevant file.
+Create a YAML file, for example, user_claude.yaml
+Paste the following content into your user_claude.yaml file.
+```yaml
+name: 'user_claude_llm'
+description: 'user claude llm with spi'
+model_name: 'claude-3-opus-20240229'
+max_tokens: 4096
+metadata:
+  type: 'LLM'
+  module: 'agentuniverse.llm.default.claude_llm'
+  class: 'ClaudeLLM'
+```
+## 2. Environment Setup
+Must be configured: ANTHROPIC_API_KEY  
+Optional: ANTHROPIC_API_URL
+### 2.1 Configure through Python code
+```python
+import os
+os.environ['ANTHROPIC_API_KEY'] = 'sk-***'
+os.environ['ANTHROPIC_API_URL'] = 'https://xxxxxx'
+```
+### 2.2 Configure through the configuration file
+In the custom_key.toml file under the config directory of the project, add the configuration:
+```toml
+ANTHROPIC_API_KEY="sk-******"
+ANTHROPIC_API_URL="https://xxxxxx"
+```
+## 3. Obtaining the ANTHROPIC API KEY
+Reference Claude Official Documentation: https://docs.anthropic.com/zh-CN/docs/getting-access-to-claude
+
+## 4. Note
+In agentuniverse, we have already created an llm with the name default_claude_llm. After configuring the ANTHROPIC_API_KEY, users can directly use it.
\ No newline at end of file
diff --git a/docs/guidebook/en/3_1_2_Ollama_LLM_Use.md b/docs/guidebook/en/3_1_2_Ollama_LLM_Use.md
new file mode 100644
index 00000000..cce2b0e6
--- /dev/null
+++ b/docs/guidebook/en/3_1_2_Ollama_LLM_Use.md
@@ -0,0 +1,32 @@
+# Ollama Usage
+## 1. Create the relevant file.
+Create a YAML file, for example, user_ollama.yaml
+Paste the following content into your user_ollama.yaml file.
+```yaml
+name: 'user_ollama_llm'
+description: 'user ollama llm with spi'
+model_name: 'qwen2:7b'
+max_tokens: 1000
+max_context_length: 32000
+metadata:
+  type: 'LLM'
+  module: 'agentuniverse.llm.default.default_ollama_llm'
+  class: 'OllamaLLM'
+```
+## 2. Environment Setup
+### 2.1 Configure through Python code
+Must be configured: OLLAMA_BASE_URL
+```python
+import os
+os.environ['OLLAMA_BASE_URL'] = 'https://xxxxxx'
+```
+### 2.2 Configure through the configuration file
+In the custom_key.toml file under the config directory of the project, add the configuration:
+```toml
+OLLAMA_BASE_URL="https://xxxxxx"
+```
+
+## 4. Tips
+In agentuniverse, we have already created an llm with the name default_ollama_llm. After configuring the OLLAMA_BASE_URL, users can directly use it.
+Reference: https://www.ollama.com/library/qwen2
+
diff --git a/docs/guidebook/en/6_2_1_Discussion_Group.md b/docs/guidebook/en/6_2_1_Discussion_Group.md
index e0d19a7d..bf8ee3c7 100644
--- a/docs/guidebook/en/6_2_1_Discussion_Group.md
+++ b/docs/guidebook/en/6_2_1_Discussion_Group.md
@@ -66,6 +66,10 @@ def chat(question: str):
 if __name__ == '__main__':
     chat("Which tastes better, Coca-Cola or Pepsi")
 ```
+### Result Demonstration
+Which tastes better, Coca-Cola or Pepsi：
+
+![Picture](../_picture/coca-cola_or_pepsi.png)
 
 ## More Details
 ### Agent Configuration
diff --git a/docs/guidebook/en/7_1_1_Legal_Consultation_Case .md b/docs/guidebook/en/7_1_1_Legal_Consultation_Case.md
similarity index 93%
rename from docs/guidebook/en/7_1_1_Legal_Consultation_Case .md
rename to docs/guidebook/en/7_1_1_Legal_Consultation_Case.md
index 57fbb680..14782290 100644
--- a/docs/guidebook/en/7_1_1_Legal_Consultation_Case .md
+++ b/docs/guidebook/en/7_1_1_Legal_Consultation_Case.md
@@ -25,7 +25,7 @@ Remove the comment from self.insert_knowledge() to rebuild the database.
 ### Law Agent
 This agent involves the following two files:
 - [law_rag_agent.py](../../../sample_standard_app/app/core/agent/rag_agent_case/law_rag_agent.py): Defines the agent's input and output
-- [law_rag_agent.py](../../../sample_standard_app/app/core/agent/rag_agent_case/law_rag_agent.yaml): Defines the agent's related prompts
+- [law_rag_agent.yaml](../../../sample_standard_app/app/core/agent/rag_agent_case/law_rag_agent.yaml): Defines the agent's related prompts
 
 
 ### Demonstration Code
diff --git a/docs/guidebook/en/7_1_1_Python_Auto_Runner.md b/docs/guidebook/en/7_1_1_Python_Auto_Runner.md
new file mode 100644
index 00000000..1832cf62
--- /dev/null
+++ b/docs/guidebook/en/7_1_1_Python_Auto_Runner.md
@@ -0,0 +1,73 @@
+# Python Auto Runner
+## Case Illustration
+This case is based on ReactPlanner, building a simple case that can automatically generate and execute Python code.
+This case is based on the QianWen large language model and the google_search function, requiring you to configure the environment variables DASHSCOPE_API_KEY, SERPER_API_KEY before use.
+
+## Quick Start
+### Configure API Key
+For example, configure key information in the file custom_key.toml where agentUniverse manages private keys (the default discussion group uses qwen as the base model and serper as the google search tool).
+```toml
+[KEY_LIST]
+# serper google search key
+SERPER_API_KEY='xxx'
+# openai api key
+DASHSCOPE_API_KEY='xxx'
+```
+
+### Agent Configuration
+```yaml
+info:
+  name: 'demo_react_agent'
+  description: 'react agent'
+profile:
+  prompt_version: qwen_react_agent.cn
+  llm_model:
+    name: 'default_qwen_llm'
+    model_name : 'qwen-max'
+    temperature: 0
+action:
+  tool:
+    - 'google_search_tool'
+    - 'python_runner'
+plan:
+  planner:
+    name: 'react_planner'
+metadata:
+  type: 'AGENT'
+  module: 'agentuniverse.agent.default.react_agent.react_agent'
+  class: 'ReActAgent'
+```
+
+Here we used two tools: google_search_tool and python_runner. The relevant tool code links are as follows:
+- [google_search_tool](../../../sample_standard_app/app/core/tool/google_search_tool.yaml)
+- [python_runner](../../../sample_standard_app/app/core/tool/python_repl_tool.yaml)
+
+
+### Case Run
+1. Test Case Run
+Directly run with test code[test_case](../../../sample_standard_app/app/test/test_react_agent.py)
+2. Interface Run
+After configuring the related keys, start the web service and use the following curl for testing.
+```shell
+curl --location --request POST 'http://localhost:8888/service_run' \
+--header 'Cookie: spanner=fQ47DxJmWYzf8rKDhs69LExySZYZFUiVXt2T4qEYgj0' \
+--header 'Content-Type: application/json' \
+--data-raw '{
+    
+    "service_id": "demo_react_service",
+    "params": {
+        "input": "请帮我生成一段python代码，可以计算三数之和"
+    }
+}'
+```
+
+### Result
+![test_case](../_picture/react_demo_step.png)
+
+In the image, React went through three steps in total:  
+Step 1: The model provided a piece of Python code and handed it over to the Python Runner tool for execution, but the execution failed due to the failure to use print to output the execution result.  
+Step 2: The model realized the mistake and proactively modified the code. It then used the Python Runner tool again for execution, which was successful.  
+Step 3: The model conveyed the successfully executed code to the user.  
+
+### Please note
+Due to limitations of the model's capabilities, it is recommended to use the qwen-max model for testing.
\ No newline at end of file
diff --git "a/docs/guidebook/zh/0_\347\233\256\345\275\225.md" "b/docs/guidebook/zh/0_\347\233\256\345\275\225.md"
index 4b26c3de..43a9b654 100644
--- "a/docs/guidebook/zh/0_\347\233\256\345\275\225.md"
+++ "b/docs/guidebook/zh/0_\347\233\256\345\275\225.md"
@@ -56,6 +56,8 @@
     * 3.1.2.3 [文心一言使用说明](3_1_2_文心使用.md)
     * 3.1.2.4 [Kimi使用说明](3_1_2_Kimi使用.md)
     * 3.1.2.5 [百川使用说明](3_1_2_百川使用.md)
+    * 3.1.2.6 [Claude使用说明](3_1_2_Claude使用.md)
+    * 3.1.2.7 [Ollama使用说明](3_1_2_Ollama使用.md)
   * 3.1.3 工具列表(Tool)
   * 3.1.4 知识列表(Knowledge)
   * 3.1.5 记忆列表(Memory)
@@ -66,6 +68,7 @@
   * 3.2.2 存储 (Store)
     * 3.2.2.1 [SQLDBWrapper](2_3_1_SQLDB_WRAPPER.md)
     * 3.2.2.2 [Milvus](3_3_1_Milvus.md)
+    * 3.2.2.3 [ChromaDB](3_3_2_ChromaDB.md)
   * 3.2.3 消息(Msg)
   * 3.2.4 日志(Logging)
     * 3.2.4.1 [阿里云SLS](3_2_4_阿里云SLS.md)
@@ -77,8 +80,15 @@
   * 5.1.1 [Docker容器化方案](5_1_1_Docker容器化部署.md)
   * 5.1.2 [K8S部署方案](5_1_2_K8S部署.md)
 
-**6.系列文章**
+**6.使用案例**
+* 6.1 RAG类Agent案例
+  * 6.1.1 [法律咨询Agent](7_1_1_法律咨询案例.md)
+* 6.2 ReAct类Agent案例
+  * 6.2.1 [Python代码生成与执行Agent](7_1_1_Python自动执行案例.md)
+* 6.3 [基于多轮多Agent的讨论小组](6_2_1_讨论组.md)
 
-**7.常见问题FAQ**
+**7.系列文章**
 
-**[8.联系我们](6_1_联系我们.md)**
+**8.常见问题FAQ**
+
+**[9.联系我们](6_1_联系我们.md)**
diff --git "a/docs/guidebook/zh/2_2_6_\350\256\241\345\210\222\345\256\232\344\271\211\344\270\216\344\275\277\347\224\250.md" "b/docs/guidebook/zh/2_2_6_\350\256\241\345\210\222\345\256\232\344\271\211\344\270\216\344\275\277\347\224\250.md"
index 0f6946db..1b8485cc 100644
--- "a/docs/guidebook/zh/2_2_6_\350\256\241\345\210\222\345\256\232\344\271\211\344\270\216\344\275\277\347\224\250.md"
+++ "b/docs/guidebook/zh/2_2_6_\350\256\241\345\210\222\345\256\232\344\271\211\344\270\216\344\275\277\347\224\250.md"
@@ -112,7 +112,7 @@ class RagPlanner(Planner):
         """
         memory: ChatMemory = self.handle_memory(agent_model, planner_input)
 
-        self.handle_all_actions(agent_model, planner_input, input_object)
+        self.run_all_actions(agent_model, planner_input, input_object)
 
         llm: LLM = self.handle_llm(agent_model)
 
diff --git "a/docs/guidebook/zh/3_1_2_0_\346\250\241\345\236\213\345\210\227\350\241\250.md" "b/docs/guidebook/zh/3_1_2_0_\346\250\241\345\236\213\345\210\227\350\241\250.md"
index 4791894c..5e62a724 100644
--- "a/docs/guidebook/zh/3_1_2_0_\346\250\241\345\236\213\345\210\227\350\241\250.md"
+++ "b/docs/guidebook/zh/3_1_2_0_\346\250\241\345\236\213\345\210\227\350\241\250.md"
@@ -1,14 +1,16 @@
 # 模型（LLM）列表
 目前平台已经接入了如下模型列表，详细使用方式请关注本章节各LLM的说明。
 
-| 模型LLM(系列)名称                  |
-|------------------------------|
-| [OpenAI](3_1_2_OpenAI使用.md)  |
-| [通义千问](3_1_2_Qwen使用.md)      |
-| [文心一言](3_1_2_文心使用.md)        |
-| [Kimi](3_1_2_Kimi使用.md)      |
-| [百川](3_1_2_百川使用.md)          |
+| 模型LLM(系列)名称                      |
+|----------------------------------|
+| [OpenAI](3_1_2_OpenAI使用.md)      |
+| [通义千问](3_1_2_Qwen使用.md)          |
+| [文心一言](3_1_2_文心使用.md)            |
+| [Kimi](3_1_2_Kimi使用.md)          |
+| [百川](3_1_2_百川使用.md)              |
+| [Claude](3_1_2_Claude使用.md)      |
+| [ollama](3_1_2_Ollama使用.md)      |
 
 未在列表中的模型您可以根据[模型定义](2_2_2_模型定义与使用.md)中的步骤自定义接入任何模型。
 
-同时我们正在添加Claude、Gemini、ollama、Llama、ZhipuAI等常见LLM的接入方式，如果您在工程中使用了这些LLM并创建了属于自己的实例，欢迎您提交pr成为agentUniverse的contributor。
\ No newline at end of file
+同时我们正在添加Gemini、Llama、ZhipuAI等常见LLM的接入方式，如果您在工程中使用了这些LLM并创建了属于自己的实例，欢迎您提交pr成为agentUniverse的contributor。
\ No newline at end of file
diff --git "a/docs/guidebook/zh/3_1_2_Claude\344\275\277\347\224\250.md" "b/docs/guidebook/zh/3_1_2_Claude\344\275\277\347\224\250.md"
new file mode 100644
index 00000000..af62c192
--- /dev/null
+++ "b/docs/guidebook/zh/3_1_2_Claude\344\275\277\347\224\250.md"
@@ -0,0 +1,34 @@
+# Claude 使用
+## 1. 创建相关文件
+创建一个yaml文件，例如 user_claude.yaml
+将以下内容粘贴到您的user_claude.yaml文件当中
+```yaml
+name: 'user_claude_llm'
+description: 'user claude llm with spi'
+model_name: 'claude-3-opus-20240229'
+max_tokens: 4096
+metadata:
+  type: 'LLM'
+  module: 'agentuniverse.llm.default.claude_llm'
+  class: 'ClaudeLLM'
+```
+## 2. 环境设置
+必须配置：ANTHROPIC_API_KEY  
+选配：ANTHROPIC_API_URL
+### 2.1 通过python代码配置
+```python
+import os
+os.environ['ANTHROPIC_API_KEY'] = 'sk-***'
+os.environ['ANTHROPIC_API_URL'] = 'https://xxxxxx'
+```
+### 2.2 通过配置文件配置
+在项目的config目录下的custom_key.toml当中，添加配置：
+```toml
+ANTHROPIC_API_KEY="sk-******"
+ANTHROPIC_API_URL="https://xxxxxx"
+```
+## 3. Claude API KEY 获取
+参考 Claude 官方文档：https://docs.anthropic.com/zh-CN/docs/getting-access-to-claude
+
+## 4. 注意
+在agentuniverse中，我们已经创建了一个name为default_claude_llm的llm,用户在配置ANTHROPIC_API_KEY之后可以直接使用
\ No newline at end of file
diff --git "a/docs/guidebook/zh/3_1_2_Ollama\344\275\277\347\224\250.md" "b/docs/guidebook/zh/3_1_2_Ollama\344\275\277\347\224\250.md"
new file mode 100644
index 00000000..dbf3ed3a
--- /dev/null
+++ "b/docs/guidebook/zh/3_1_2_Ollama\344\275\277\347\224\250.md"
@@ -0,0 +1,32 @@
+# Ollama 使用
+## 1. 创建相关文件
+创建一个yaml文件，例如 user_ollama.yaml
+将以下内容粘贴到您的user_ollama.yaml文件当中
+```yaml
+name: 'user_ollama_llm'
+description: 'user ollama llm with spi'
+model_name: 'qwen2:7b'
+max_tokens: 1000
+max_context_length: 32000
+metadata:
+  type: 'LLM'
+  module: 'agentuniverse.llm.default.default_ollama_llm'
+  class: 'OllamaLLM'
+```
+## 2. 环境设置
+### 2.1 通过python代码配置
+必须配置：OLLAMA_BASE_URL
+```python
+import os
+os.environ['OLLAMA_BASE_URL'] = 'https://xxxxxx'
+```
+### 2.2 通过配置文件配置
+在项目的config目录下的custom_key.toml当中，添加配置：
+```toml
+OLLAMA_BASE_URL="https://xxxxxx"
+```
+
+## 3. Tips
+在agentuniverse中，我们已经创建了一个name为default_ollama_llm的llm,用户在配置OLLAMA_BASE_URL之后可以直接使用。
+使用ollama参考官方地址：https://www.ollama.com/library/qwen2
+
diff --git "a/docs/guidebook/zh/6_2_1_\350\256\250\350\256\272\347\273\204.md" "b/docs/guidebook/zh/6_2_1_\350\256\250\350\256\272\347\273\204.md"
index a3289267..e974458e 100644
--- "a/docs/guidebook/zh/6_2_1_\350\256\250\350\256\272\347\273\204.md"
+++ "b/docs/guidebook/zh/6_2_1_\350\256\250\350\256\272\347\273\204.md"
@@ -38,6 +38,14 @@ def chat(question: str):
 if __name__ == '__main__':
     chat("甜粽子好吃还是咸粽子好吃")
 ```
+### 效果演示
+甜粽子好吃还是咸粽子好吃：
+
+![演示图片](../_picture/sweet_or_salted_zongzi.png)
+
+中医好还是西医好：
+
+![演示图片](../_picture/chinese_or_western_medicine.png)
 
 ## 更多细节
 ### 智能体配置
diff --git "a/docs/guidebook/zh/7_1_1_Python\350\207\252\345\212\250\346\211\247\350\241\214\346\241\210\344\276\213.md" "b/docs/guidebook/zh/7_1_1_Python\350\207\252\345\212\250\346\211\247\350\241\214\346\241\210\344\276\213.md"
new file mode 100644
index 00000000..729c2773
--- /dev/null
+++ "b/docs/guidebook/zh/7_1_1_Python\350\207\252\345\212\250\346\211\247\350\241\214\346\241\210\344\276\213.md"
@@ -0,0 +1,74 @@
+# Python自动执行案例
+## 案例说明
+本案例基于ReactPlanner，搭建了一个简单可以自动生成python代码并执行的案例。
+
+该案例基于千问大模型和`goolge_search`功能，使用前需要您在环境变量中配置`DASHSCOPE_API_KEY`、`SERPER_API_KEY`。
+
+## 快速开始
+### 配置API密钥
+比如在agentUniverse管理私有密钥配置的文件`custom_key.toml`中配置密钥信息（讨论组默认使用qwen作为基座模型，serper作为google search工具）
+```toml
+[KEY_LIST]
+# serper google search key
+SERPER_API_KEY='xxx'
+# openai api key
+DASHSCOPE_API_KEY='xxx'
+```
+
+### 创建Agent
+```yaml
+info:
+  name: 'demo_react_agent'
+  description: 'react agent'
+profile:
+  prompt_version: qwen_react_agent.cn
+  llm_model:
+    name: 'default_qwen_llm'
+    model_name : 'qwen-max'
+    temperature: 0
+action:
+  tool:
+    - 'google_search_tool'
+    - 'python_runner'
+plan:
+  planner:
+    name: 'react_planner'
+metadata:
+  type: 'AGENT'
+  module: 'agentuniverse.agent.default.react_agent.react_agent'
+  class: 'ReActAgent'
+```
+
+这里使用了google_search_tool与python_runner两个工具，相关工具代码链接如下：
+- [google_search_tool](../../../sample_standard_app/app/core/tool/google_search_tool.yaml)
+- [python_runner](../../../sample_standard_app/app/core/tool/python_repl_tool.yaml)
+
+
+### 代码运行
+1. 测试用例运行
+直接使用测试代码运行[test_case](../../../sample_standard_app/app/test/test_react_agent.py)
+2. 接口运行
+配置好相关key之后，启动web服务，使用下面的curl进行测试
+```shell
+curl --location --request POST 'http://localhost:8888/service_run' \
+--header 'Cookie: spanner=fQ47DxJmWYzf8rKDhs69LExySZYZFUiVXt2T4qEYgj0' \
+--header 'Content-Type: application/json' \
+--data-raw '{
+    
+    "service_id": "demo_react_service",
+    "params": {
+        "input": "请帮我生成一段python代码，可以计算三数之和"
+    }
+}'
+```
+
+### 执行结果
+![test_case](../_picture/react_demo_step.png)
+
+图片中，react一共执行了三步：  
+    第一步，模型根据问题给出了一段python代码，并交给python_runner工具执行，但是执行失败了，失败原因是没有使用print打印执行结果。  
+    第二步，模型意识到错误，主动修改了代码，再次使用python_runner工具执行，执行成功。  
+    第三步，模型将执行成功的代码告诉给用户。  
+
+### 注意
+受限于模型能力问题，建议使用qwen-max模型进行测试
\ No newline at end of file
diff --git "a/docs/guidebook/zh/7_1_1_\346\263\225\345\276\213\345\222\250\350\257\242\346\241\210\344\276\213.md" "b/docs/guidebook/zh/7_1_1_\346\263\225\345\276\213\345\222\250\350\257\242\346\241\210\344\276\213.md"
index 76919c47..c7d8b7c7 100644
--- "a/docs/guidebook/zh/7_1_1_\346\263\225\345\276\213\345\222\250\350\257\242\346\241\210\344\276\213.md"
+++ "b/docs/guidebook/zh/7_1_1_\346\263\225\345\276\213\345\222\250\350\257\242\346\241\210\344\276\213.md"
@@ -25,7 +25,7 @@
 ### 法律智能体
 该智能体涉及如下两个文件： 
 - [law_rag_agent.py](../../../sample_standard_app/app/core/agent/rag_agent_case/law_rag_agent.py): 定义了智能体的输入和输出
-- [law_rag_agent.py](../../../sample_standard_app/app/core/agent/rag_agent_case/law_rag_agent.yaml): 定义了智能体的相关提示词
+- [law_rag_agent.yaml](../../../sample_standard_app/app/core/agent/rag_agent_case/law_rag_agent.yaml): 定义了智能体的相关提示词
 
 
 ### 演示代码
diff --git a/pyproject.toml b/pyproject.toml
index e6ab5832..e29498b8 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
 [tool.poetry]
 name = "agentUniverse"
-version = "0.0.8"
+version = "0.0.9"
 description = "agentUniverse is a framework for developing applications powered by multi-agent base on large language model."
 
 authors = ["AntGroup <jerry.zzw@antgroup.com>"]
@@ -49,6 +49,8 @@ myst-parser = "^2.0.0"
 qianfan = "^0.3.12"
 dashscope = "^1.19.1"
 anthropic = "^0.26.0"
+ollama = '^0.2.1'
+langchain-anthropic = '^0.1.13'
 
 [tool.poetry.extras]
 log_ext = ["aliyun-log-python-sdk"]
diff --git a/sample_standard_app/app/bootstrap/server_application.py b/sample_standard_app/app/bootstrap/server_application.py
index 3f59fb94..cb5cb908 100644
--- a/sample_standard_app/app/bootstrap/server_application.py
+++ b/sample_standard_app/app/bootstrap/server_application.py
@@ -5,6 +5,7 @@
 # @Author  : jerry.zzw 
 # @Email   : jerry.zzw@antgroup.com
 # @FileName: server_application.py
+
 from agentuniverse.agent_serve.web.web_booster import start_web_server
 from agentuniverse.base.agentuniverse import AgentUniverse
 
diff --git a/sample_standard_app/app/core/agent/nl2api_agent_case/__init__.py b/sample_standard_app/app/core/agent/nl2api_agent_case/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/sample_standard_app/app/core/agent/nl2api_agent_case/nl2api_agent.yaml b/sample_standard_app/app/core/agent/nl2api_agent_case/nl2api_agent.yaml
new file mode 100644
index 00000000..2bf6c79d
--- /dev/null
+++ b/sample_standard_app/app/core/agent/nl2api_agent_case/nl2api_agent.yaml
@@ -0,0 +1,20 @@
+info:
+  name: 'demo_nl2api_agent'
+  description: 'demo nl2api agent'
+profile:
+  llm_model:
+    name: 'default_qwen_llm'
+action:
+  tool:
+    - 'add'
+    - 'sub'
+    - 'mul'
+    - 'div'
+    - 'google_search_tool'
+plan:
+  planner:
+    name: 'nl2api_planner'
+metadata:
+  type: 'AGENT'
+  module: 'agentuniverse.agent.default.nl2api_agent.nl2api_agent'
+  class: 'Nl2ApiAgent'
\ No newline at end of file
diff --git a/sample_standard_app/app/core/agent/rag_agent_case/demo_rag_agent.yaml b/sample_standard_app/app/core/agent/rag_agent_case/demo_rag_agent.yaml
index 8457d2df..fecdd274 100644
--- a/sample_standard_app/app/core/agent/rag_agent_case/demo_rag_agent.yaml
+++ b/sample_standard_app/app/core/agent/rag_agent_case/demo_rag_agent.yaml
@@ -24,8 +24,8 @@ profile:
 
     需要回答的问题是: {input}
   llm_model:
-    name: 'demo_llm'
-    model_name: 'gpt-4o'
+    name: 'default_qwen_llm'
+#    model_name: 'gpt-4o'
 plan:
   planner:
     name: 'rag_planner'
diff --git a/sample_standard_app/app/core/agent/react_agent_case/__init__.py b/sample_standard_app/app/core/agent/react_agent_case/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/sample_standard_app/app/core/agent/react_agent_case/demo_react_agent.yaml b/sample_standard_app/app/core/agent/react_agent_case/demo_react_agent.yaml
new file mode 100644
index 00000000..8a38838d
--- /dev/null
+++ b/sample_standard_app/app/core/agent/react_agent_case/demo_react_agent.yaml
@@ -0,0 +1,19 @@
+info:
+  name: 'demo_react_agent'
+  description: 'react agent'
+profile:
+  prompt_version: qwen_react_agent.cn
+  llm_model:
+    name: 'default_qwen_llm'
+    temperature: 0
+action:
+  tool:
+    - 'google_search_tool'
+    - 'python_runner'
+plan:
+  planner:
+    name: 'react_planner'
+metadata:
+  type: 'AGENT'
+  module: 'agentuniverse.agent.default.react_agent.react_agent'
+  class: 'ReActAgent'
\ No newline at end of file
diff --git a/sample_standard_app/app/core/llm/qwen_llm.yaml b/sample_standard_app/app/core/llm/qwen_llm.yaml
index ab5c0742..1115947c 100644
--- a/sample_standard_app/app/core/llm/qwen_llm.yaml
+++ b/sample_standard_app/app/core/llm/qwen_llm.yaml
@@ -1,7 +1,6 @@
 name: 'qwen_llm'
 description: 'demo qwen llm with spi'
 model_name: 'qwen-max'
-
 max_tokens: 2000
 metadata:
   type: 'LLM'
diff --git a/sample_standard_app/app/core/prompt/demo_react_prompt.yaml b/sample_standard_app/app/core/prompt/demo_react_prompt.yaml
new file mode 100644
index 00000000..4282da89
--- /dev/null
+++ b/sample_standard_app/app/core/prompt/demo_react_prompt.yaml
@@ -0,0 +1,40 @@
+introduction: 你是一个精通工具使用的AI助手。
+target: 你的目标是根据用户的问题以及给出的背景信息，使用工具回答用户的问题。尤其擅长使用搜索或者使用执行python代码解决问题
+instruction: |
+  你必须优先选择使用提供的工具回答用户提出的问题，若用户没有提供工具可以根据你的通识能力解决问题。
+  你在回答时问题必须使用中文回答。
+  你必须从多个角度、维度分析用户的问题，帮助用户获取最全面的信息，需要根据背景和问题，决定搜索哪些信息可以回答问题。 
+  你必须把大问题拆解为多个小问题，并规划解决步骤。
+  
+  您可以使用以下工具:
+  {tools}
+  
+  你的回答必须严格使用以下格式:
+  
+    Question: 您必须回答的问题
+    Thought: 我这一步应该做什么，为什么要这么做，我现在要使用一个工具, 不允许回答Final Answer
+    Action: 要使用的工具应该，值必须是 [{tool_names}] 之一
+    Action Input: 工具的输入
+    Observation: 工具的执行结果
+    ... (Thought/Action/Action Input/Observation 的过程可以重复 N 次)
+    Thought: 我现在知道所有问题的最终答案了
+    Final Answer: 所有问题的最终答案
+  
+  之前的对话:
+  {chat_history}
+  
+  背景信息是:
+  {background}
+  
+  开始！
+    注意：
+      1.你的回答必须是（Thought/Action/Observation）与（Thought/Final Answer）两种格式之一
+      2.你现在必须根据上一步Observation的结果（成功、失败、报错，信息不完整），判断下一步要执行的动作
+  
+  Question: {input}
+  Thought: {agent_scratchpad}
+  
+
+metadata:
+  type: 'PROMPT'
+  version: 'qwen_react_agent.cn'
diff --git a/sample_standard_app/app/core/prompt/host_agent_cn.yaml b/sample_standard_app/app/core/prompt/host_agent_cn.yaml
index b59d7573..e8d01aac 100644
--- a/sample_standard_app/app/core/prompt/host_agent_cn.yaml
+++ b/sample_standard_app/app/core/prompt/host_agent_cn.yaml
@@ -1,4 +1,4 @@
-introduction: 你是一位精通信息分析的ai问答助手。
+introduction: 你是一位精通信息分析的问答助手。
 target: 人类给你一个问题，你的目标是根据几个讨论组里参与者多轮讨论的结果，给人类一个准确的答案。
 instruction: |
   你需要遵守的规则是:
diff --git a/sample_standard_app/app/core/prompt/host_agent_en.yaml b/sample_standard_app/app/core/prompt/host_agent_en.yaml
index 9c0ec947..16beaaf9 100644
--- a/sample_standard_app/app/core/prompt/host_agent_en.yaml
+++ b/sample_standard_app/app/core/prompt/host_agent_en.yaml
@@ -1,4 +1,4 @@
-introduction: You are an AI Q&A assistant proficient in information analysis.
+introduction: You are a Q&A assistant proficient in information analysis.
 target: Human gives you a question, and your goal is to give human an accurate answer based on the results of multiple rounds of discussion among the participants in the discussion group.
 instruction: |
   The rules you need to follow are:
diff --git a/sample_standard_app/app/core/prompt/participant_agent_cn.yaml b/sample_standard_app/app/core/prompt/participant_agent_cn.yaml
index 63cb3a25..39774c99 100644
--- a/sample_standard_app/app/core/prompt/participant_agent_cn.yaml
+++ b/sample_standard_app/app/core/prompt/participant_agent_cn.yaml
@@ -1,4 +1,4 @@
-introduction: 你是一位精通信息分析的ai问答助手。
+introduction: 你是一位精通信息分析的问答助手。
 target: 人类给你一个问题，你的目标是和另外几个讨论的参与者共同讨论，最后结合多轮的讨论对话结果，给人类一个准确的答案。
 instruction: |
   你需要遵守的规则是:
diff --git a/sample_standard_app/app/core/prompt/participant_agent_en.yaml b/sample_standard_app/app/core/prompt/participant_agent_en.yaml
index b5fe2d88..aa39313e 100644
--- a/sample_standard_app/app/core/prompt/participant_agent_en.yaml
+++ b/sample_standard_app/app/core/prompt/participant_agent_en.yaml
@@ -1,4 +1,4 @@
-introduction: You are an AI Q&A assistant proficient in information analysis.
+introduction: You are a Q&A assistant proficient in information analysis.
 target: Human gives you a question, and your goal is to discuss with several other participants in the discussion, and finally, combined with the results of many rounds of discussion, to give human an accurate answer.
 instruction: |
   The rules you need to follow are:
diff --git a/sample_standard_app/app/core/service/demo_react_service.yaml b/sample_standard_app/app/core/service/demo_react_service.yaml
new file mode 100644
index 00000000..a8718c13
--- /dev/null
+++ b/sample_standard_app/app/core/service/demo_react_service.yaml
@@ -0,0 +1,5 @@
+name: 'demo_react_service'
+description: 'demo react service of demo agent'
+agent: 'demo_react_agent'
+metadata:
+  type: 'SERVICE'
\ No newline at end of file
diff --git a/sample_standard_app/app/core/tool/add_simple_tool.yaml b/sample_standard_app/app/core/tool/add_simple_tool.yaml
new file mode 100644
index 00000000..d5dda037
--- /dev/null
+++ b/sample_standard_app/app/core/tool/add_simple_tool.yaml
@@ -0,0 +1,8 @@
+name: 'add'
+description: 'Adding two float number, input_params with 2 num spilt with comma, return result. For example, input_params = 1, 2 , the result = 3'
+tool_type: 'api'
+input_keys: ['input']
+metadata:
+  type: 'TOOL'
+  module: 'sample_standard_app.app.core.tool.simple_math_tool'
+  class: 'AddTool'
\ No newline at end of file
diff --git a/sample_standard_app/app/core/tool/div_simple_tool.yaml b/sample_standard_app/app/core/tool/div_simple_tool.yaml
new file mode 100644
index 00000000..eea3425d
--- /dev/null
+++ b/sample_standard_app/app/core/tool/div_simple_tool.yaml
@@ -0,0 +1,8 @@
+name: 'div'
+description: 'Dividing two float number, input_params with 2 num spilt with comma, return result. For example, input_params = 6, 3 , the result = 2'
+tool_type: 'api'
+input_keys: ['input']
+metadata:
+  type: 'TOOL'
+  module: 'sample_standard_app.app.core.tool.simple_math_tool'
+  class: 'MultiplyTool'
\ No newline at end of file
diff --git a/sample_standard_app/app/core/tool/google_search_tool.py b/sample_standard_app/app/core/tool/google_search_tool.py
index 50b14d7e..22da460a 100644
--- a/sample_standard_app/app/core/tool/google_search_tool.py
+++ b/sample_standard_app/app/core/tool/google_search_tool.py
@@ -9,6 +9,7 @@
 from pydantic import Field
 from langchain_community.utilities.google_serper import GoogleSerperAPIWrapper
 from agentuniverse.agent.action.tool.tool import Tool, ToolInput
+from agentuniverse.base.config.component_configer.configers.tool_configer import ToolConfiger
 from agentuniverse.base.util.env_util import get_from_env
 
 from sample_standard_app.app.core.tool.mock_search_tool import MockSearchTool
@@ -26,9 +27,9 @@ class GoogleSearchTool(Tool):
     serper_api_key: Optional[str] = Field(default_factory=lambda: get_from_env("SERPER_API_KEY"))
 
     def execute(self, tool_input: ToolInput):
+        input = tool_input.get_data("input")
         if self.serper_api_key is None:
-            return MockSearchTool().execute(tool_input)
-        query = tool_input.get_data("input")
+            return MockSearchTool().execute(tool_input=tool_input)
         # get top10 results from Google search.
         search = GoogleSerperAPIWrapper(serper_api_key=self.serper_api_key, k=10, gl="us", hl="en", type="search")
-        return search.run(query=query)
+        return search.run(query=input)
\ No newline at end of file
diff --git a/sample_standard_app/app/core/tool/google_search_tool.yaml b/sample_standard_app/app/core/tool/google_search_tool.yaml
index 93ca5659..c8ed4af3 100644
--- a/sample_standard_app/app/core/tool/google_search_tool.yaml
+++ b/sample_standard_app/app/core/tool/google_search_tool.yaml
@@ -1,5 +1,9 @@
 name: 'google_search_tool'
-description: 'demo google search tool'
+description: |
+  该工具可以用来进行谷歌搜索，工具的输入是你想搜索的内容。
+  工具输入示例：
+    示例1: 你想要搜索上海的天气时，工具的输入应该是：上海今天的天气
+    示例2: 你想要搜索日本的天气时，工具的输入应该是：日本的天气
 tool_type: 'api'
 input_keys: ['input']
 metadata:
diff --git a/sample_standard_app/app/core/tool/mock_search_tool.py b/sample_standard_app/app/core/tool/mock_search_tool.py
index ebd78516..f0b85660 100644
--- a/sample_standard_app/app/core/tool/mock_search_tool.py
+++ b/sample_standard_app/app/core/tool/mock_search_tool.py
@@ -41,5 +41,6 @@ class MockSearchTool(Tool):
     """
 
     def execute(self, tool_input: ToolInput):
+        input = tool_input.get_data("input")
         """Demonstrates the execute method of the Tool class."""
         return MOCK_SEARCH_RESULT
diff --git a/sample_standard_app/app/core/tool/mul_simple_tool.yaml b/sample_standard_app/app/core/tool/mul_simple_tool.yaml
new file mode 100644
index 00000000..ca5e95c7
--- /dev/null
+++ b/sample_standard_app/app/core/tool/mul_simple_tool.yaml
@@ -0,0 +1,8 @@
+name: 'mul'
+description: 'Multiplying two float number, input_params with 2 num spilt with comma, return result. For example, a = 2, 1 , the result = 2'
+tool_type: 'api'
+input_keys: ['input']
+metadata:
+  type: 'TOOL'
+  module: 'sample_standard_app.app.core.tool.simple_math_tool'
+  class: 'MultiplyTool'
\ No newline at end of file
diff --git a/sample_standard_app/app/core/tool/python_repl.py b/sample_standard_app/app/core/tool/python_repl.py
new file mode 100644
index 00000000..04af11c1
--- /dev/null
+++ b/sample_standard_app/app/core/tool/python_repl.py
@@ -0,0 +1,41 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+
+# @Time    : 2024/6/12 16:36
+# @Author  : weizjajj 
+# @Email   : weizhongjie.wzj@antgroup.com
+# @FileName: python_repl.py
+
+import re
+
+from langchain_community.utilities import PythonREPL
+from pydantic import Field
+from agentuniverse.agent.action.tool.tool import Tool, ToolInput
+
+
+class PythonREPLTool(Tool):
+    """The mock search tool.
+
+    In this tool, we mocked the search engine's answers to search for information about BYD and Warren Buffett.
+
+    Note:
+        The tool is only suitable for users searching for Buffett or BYD related queries.
+        We recommend that you configure your `SERPER_API_KEY` and use google_search_tool to get information.
+    """
+    client: PythonREPL = Field(default_factory=lambda: PythonREPL())
+
+    def execute(self, tool_input: ToolInput):
+        input = tool_input.get_data("input")
+        """Demonstrates the execute method of the Tool class."""
+        pattern = re.compile(r"```python(.*?)``", re.DOTALL)
+        matches = pattern.findall(input)
+        if len(matches) == 0:
+            pattern = re.compile(r"```py(.*?)``", re.DOTALL)
+            matches = pattern.findall(input)
+        if len(matches) == 0:
+            return self.client.run(input)
+        res = self.client.run(matches[0])
+        if res == "" or res is None:
+            return "ERROR: 你的python代码中没有使用print输出任何内容，请参考工具示例"
+        else:
+            return res
diff --git a/sample_standard_app/app/core/tool/python_repl_tool.yaml b/sample_standard_app/app/core/tool/python_repl_tool.yaml
new file mode 100644
index 00000000..5ec69b46
--- /dev/null
+++ b/sample_standard_app/app/core/tool/python_repl_tool.yaml
@@ -0,0 +1,19 @@
+name: 'python_runner'
+description: '使用该工具可以执行python代码，可以在pycharm中直接运行的代码.工具的输入必须时一段有效的python代码. 如何你想要查看工具的执行结果, 必须在python代码中使用print(...)打印你想查看的内容。
+    工具输入示例：
+      你想要计算1+3等于多少时，工具的输入应该是：
+        ```py 
+        print(1+3)
+        ```
+      你想要获取百度页面的信息时，工具的输入应该是: 
+        ```py 
+        import requests
+        resp=requests.get("https://www.baidu.com")
+        print(resp.content)
+        ```'
+tool_type: 'api'
+input_keys: ['input']
+metadata:
+  type: 'TOOL'
+  module: 'sample_standard_app.app.core.tool.python_repl'
+  class: 'PythonREPLTool'
\ No newline at end of file
diff --git a/sample_standard_app/app/core/tool/search_api_baidu_tool.yaml b/sample_standard_app/app/core/tool/search_api_baidu_tool.yaml
new file mode 100644
index 00000000..ed1c4e84
--- /dev/null
+++ b/sample_standard_app/app/core/tool/search_api_baidu_tool.yaml
@@ -0,0 +1,12 @@
+name: 'search_api_baidu_tool'
+description: '百度(必应)搜索工具，输入为一个要搜索内容的字符串，例如：input=黄金价格是多少'
+tool_type: 'api'
+input_keys: ['input']
+engine: 'baidu'
+search_type: 'json'
+search_params:
+  num: 10
+metadata:
+  type: 'TOOL'
+  module: 'sample_standard_app.app.core.tool.search_api_tool'
+  class: 'SearchAPITool'
\ No newline at end of file
diff --git a/sample_standard_app/app/core/tool/search_api_bing_tool.yaml b/sample_standard_app/app/core/tool/search_api_bing_tool.yaml
new file mode 100644
index 00000000..f4e8d08f
--- /dev/null
+++ b/sample_standard_app/app/core/tool/search_api_bing_tool.yaml
@@ -0,0 +1,12 @@
+name: 'search_api_bing_tool'
+description: 'Bing(必应)搜索工具，输入为一个要搜索内容的字符串，例如：input=黄金价格是多少'
+tool_type: 'api'
+input_keys: ['input']
+engine: 'bing'
+search_type: 'common'
+search_params:
+  num: 10
+metadata:
+  type: 'TOOL'
+  module: 'sample_standard_app.app.core.tool.search_api_tool'
+  class: 'SearchAPITool'
\ No newline at end of file
diff --git a/sample_standard_app/app/core/tool/search_api_tool.py b/sample_standard_app/app/core/tool/search_api_tool.py
new file mode 100644
index 00000000..20032ca1
--- /dev/null
+++ b/sample_standard_app/app/core/tool/search_api_tool.py
@@ -0,0 +1,68 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+import os
+# @Time    : 2024/6/12 09:44
+# @Author  : weizjajj 
+# @Email   : weizhongjie.wzj@antgroup.com
+# @FileName: search_api_tool.py
+
+
+from typing import Optional
+
+from langchain_community.utilities import SearchApiAPIWrapper
+from pydantic import Field
+
+from agentuniverse.agent.action.tool.tool import Tool, ToolInput
+from agentuniverse.base.config.component_configer.configers.tool_configer import ToolConfiger
+from agentuniverse.base.util.env_util import get_from_env
+
+
+class SearchAPITool(Tool):
+    """
+    The demo search tool.
+
+    Implement the execute method of demo google search tool, using the `SearchApiAPIWrapper` to implement a simple search.
+
+    Note:
+        You need to sign up for a free account at https://www.searchapi.io/ and get the SEARCHAPI_API_KEY api key (100 free queries).
+
+    Args:
+        search_api_key: Optional[str] = Field(default_factory=lambda: get_from_env("SEARCHAPI_API_KEY")),
+        engine: str = "google" engine type you want to use
+        search_params: dict = {} engine search parameters
+        search_type: str = "common" result type you want to get ,common string or json
+    """
+
+    search_api_key: Optional[str] = Field(default_factory=lambda: get_from_env("SEARCHAPI_API_KEY"))
+    engine: str = "google"
+    search_params: dict = {}
+    search_api_wrapper: Optional[SearchApiAPIWrapper] = None
+    search_type: str = "common"
+
+    def _load_api_wapper(self):
+        if not self.search_api_key:
+            raise ValueError("Please set the SEARCHAPI_API_KEY environment variable.")
+        if not self.search_api_wrapper:
+            self.search_api_wrapper = SearchApiAPIWrapper(searchapi_api_key=self.search_api_key, engine=self.engine)
+        return self.search_api_wrapper
+
+    def execute(self, tool_input: ToolInput):
+        self._load_api_wapper()
+        search_params = {}
+        for k, v in self.search_params.items():
+            if k in tool_input.to_dict():
+                search_params[k] = tool_input.get_data(k)
+                continue
+            search_params[k] = v
+        input = tool_input.get_data("input")
+        if self.search_type == "json":
+            return self.search_api_wrapper.results(query=input, **search_params)
+        return self.search_api_wrapper.run(query=input, **search_params)
+
+    def initialize_by_component_configer(self, component_configer: ToolConfiger) -> 'Tool':
+        """Initialize the tool by the component configer."""
+        super().initialize_by_component_configer(component_configer)
+        self.engine = component_configer.configer.value.get('engine', 'google')
+        self.search_params = component_configer.configer.value.get('search_params', {})
+        self.search_type = component_configer.configer.value.get('search_type', 'common')
+        return self
diff --git a/sample_standard_app/app/core/tool/simple_math_tool.py b/sample_standard_app/app/core/tool/simple_math_tool.py
new file mode 100644
index 00000000..bca1e0e2
--- /dev/null
+++ b/sample_standard_app/app/core/tool/simple_math_tool.py
@@ -0,0 +1,43 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+from langchain_core.utils.json import parse_json_markdown
+
+# @Time    : 2024/6/11 09:49
+# @Author  : weizjajj 
+# @Email   : weizhongjie.wzj@antgroup.com
+# @FileName: simple_math_tool.py
+
+
+from agentuniverse.agent.action.tool.tool import Tool, ToolInput
+
+
+class AddTool(Tool):
+    def execute(self, tool_input: ToolInput):
+        input_params = tool_input.get_data('input')
+        a, b = input_params.split(',')
+        result = float(a) + float(b)
+        return result
+
+
+class SubtractTool(Tool):
+    def execute(self,  tool_input: ToolInput):
+        input_params = tool_input.get_data('input')
+        a, b = input_params.split(',')
+        result = float(a) - float(b)
+        return result
+
+
+class MultiplyTool(Tool):
+    def execute(self,  tool_input: ToolInput):
+        input_params = tool_input.get_data('input')
+        a, b = input_params.split(',')
+        result = float(a) * float(b)
+        return result
+
+
+class DivideTool(Tool):
+    def execute(self,  tool_input: ToolInput):
+        input_params = tool_input.get_data('input')
+        a, b = input_params.split(',')
+        result = float(a) / float(b)
+        return result
diff --git a/sample_standard_app/app/core/tool/sub_simple_tool.yaml b/sample_standard_app/app/core/tool/sub_simple_tool.yaml
new file mode 100644
index 00000000..2a2e6706
--- /dev/null
+++ b/sample_standard_app/app/core/tool/sub_simple_tool.yaml
@@ -0,0 +1,8 @@
+name: 'sub'
+description: 'Subtracting two float number, input_params with 2 num spilt with comma, return result. For example, input_params = 2, 1 , the result = 1'
+tool_type: 'api'
+input_keys: ['input']
+metadata:
+  type: 'TOOL'
+  module: 'sample_standard_app.app.core.tool.simple_math_tool'
+  class: 'SubtractTool'
\ No newline at end of file


Test patch:
diff --git a/sample_standard_app/app/test/test_nl2api_agent.py b/sample_standard_app/app/test/test_nl2api_agent.py
new file mode 100644
index 00000000..6ab794c8
--- /dev/null
+++ b/sample_standard_app/app/test/test_nl2api_agent.py
@@ -0,0 +1,29 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+
+# @Time    : 2024/6/4 21:27
+# @Author  : wangchongshi
+# @Email   : wangchongshi.wcs@antgroup.com
+# @FileName: test_react_agent.py
+import unittest
+
+from agentuniverse.agent.agent import Agent
+from agentuniverse.agent.agent_manager import AgentManager
+from agentuniverse.agent.output_object import OutputObject
+from agentuniverse.base.agentuniverse import AgentUniverse
+
+
+class ReActAgentTest(unittest.TestCase):
+
+    def setUp(self) -> None:
+        AgentUniverse().start(config_path='../../config/config.toml')
+
+    def test_react_agent(self):
+        """Test demo reAct agent."""
+        instance: Agent = AgentManager().get_instance_obj('demo_nl2api_agent')
+        output_object: OutputObject = instance.run(input='1+3/2+10-4*3等于多少')
+        print(output_object.to_dict())
+
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/sample_standard_app/app/test/test_react_agent.py b/sample_standard_app/app/test/test_react_agent.py
new file mode 100644
index 00000000..77534dbd
--- /dev/null
+++ b/sample_standard_app/app/test/test_react_agent.py
@@ -0,0 +1,28 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+
+# @Time    : 2024/6/4 21:27
+# @Author  : wangchongshi
+# @Email   : wangchongshi.wcs@antgroup.com
+# @FileName: test_react_agent.py
+import unittest
+
+from agentuniverse.agent.agent import Agent
+from agentuniverse.agent.agent_manager import AgentManager
+from agentuniverse.agent.output_object import OutputObject
+from agentuniverse.base.agentuniverse import AgentUniverse
+
+
+class ReActAgentTest(unittest.TestCase):
+
+    def setUp(self) -> None:
+        AgentUniverse().start(config_path='../../config/config.toml')
+
+    def test_react_agent(self):
+        """Test demo reAct agent."""
+        instance: Agent = AgentManager().get_instance_obj('demo_react_agent')
+        output_object: OutputObject = instance.run(input='请给出一段python代码，可以计算三数之和，给出之前必须验证代码是否可以运行，最少验证三次')
+
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/sample_standard_app/app/test/test_search_tool.py b/sample_standard_app/app/test/test_search_tool.py
new file mode 100644
index 00000000..f442fad5
--- /dev/null
+++ b/sample_standard_app/app/test/test_search_tool.py
@@ -0,0 +1,23 @@
+import os
+import unittest
+
+from agentuniverse.agent.action.tool.tool_manager import ToolManager
+from agentuniverse.base.agentuniverse import AgentUniverse
+
+
+class SearchToolTest(unittest.TestCase):
+    """
+    Test cases for the rag agent
+    """
+
+    def setUp(self) -> None:
+        AgentUniverse().start(config_path='../../config/config.toml')
+
+    def test_rag_agent(self):
+        """Test demo rag agent."""
+        res = ToolManager().get_instance_obj("baidu_search_tool").run(input="今日黄金价格")
+        print(res)
+
+
+if __name__ == '__main__':
+    unittest.main()