Repository: antgroup/agentUniverse (language: python)

Issue:
feat: Initial core package
Add agent action, memory and llm module to agentUniverse


Discussion / hints:

Fix patch:
diff --git a/README.md b/README.md
index c2bd5c5d..e42783d1 100644
--- a/README.md
+++ b/README.md
@@ -1,1 +1,48 @@
-# AgentUniverse
\ No newline at end of file
+# agentUniverse
+****************************************
+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.3-blue?logo=pypi)](https://pypi.org/project/agentUniverse/)
+
+![](https://github.com/alipay/agentUniverse/blob/master/docs/guidebook/_picture/logo_bar.png)
+****************************************
+
+## Overview
+agentUniverse is a framework for developing applications powered by multi-agent base on large language model.  It provides all the essential components for building a single agent, and a multi-agent collaboration mechanism which  serves as a pattern factory that allowing developers to buid and customize multi-agent collaboration patterns. With this framework,  developers can easily construct multi-agent applications, and share the pattern practices from different technical  and business fields.
+
+The framework will come with serveral pre-install multi-agent collaboration patterns which have been proven effective in real business scenarios, and will continue to be enriched in the future. Patterns that are currently about to be released include:
+
+- PEER pattern：
+This pattern utilizes four distinct agent roles: Plan, Execute, Express, and Review, to achieve a multi-step breakdown and sequential execution of a complex task. It also performs autonomous iteration based on evaluative feedback which enhancing performance in reasoning and analytical tasks. 
+
+
+- DOE pattern：
+This pattern consists of three agents: Data-fining agent, which is designed to solve data-intensive and high-computational-precision task; Opinion-inject agent, which combines the data results from first agent and the expert opinions which are pre-collected and structured; the third agent, Express agent generates the final result base on given document type and language style.
+
+More patterns are coming soon...
+
+![](https://github.com/alipay/agentUniverse/blob/master/docs/guidebook/_picture/agent_universe_framework_resize.jpg)
+
+## agentUniverseSample Project
+[agentUniverse Sample Project](https://github.com/alipay/agentUniverse/blob/master/sample_standard_app/README.md)
+
+## Quick Installation
+Using pip:
+```shell
+pip install agentUniverse
+```
+
+## Quick Start
+We will show you how to:
+* Prepare the environment and application project
+* Build a simple agent
+* Use pattern components to complete multi-agent collaboration
+* Test and optimize the performance of the agent
+* Quickly serve the agent
+For details, please read [Quick Start](https://github.com/alipay/agentUniverse/blob/master/docs/guidebook/en/1_3_Quick_Start.md).
+
+## Guidebook
+For more detailed information, please refer to the [Guidebook](https://github.com/alipay/agentUniverse/blob/master/docs/guidebook/en/0_index.md).
diff --git a/README_zh.md b/README_zh.md
index aa4a1f24..776acc6b 100644
--- a/README_zh.md
+++ b/README_zh.md
@@ -1,1 +1,51 @@
-# AgentUniverse
+# agentUniverse
+****************************************
+语言版本: [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.3-blue?logo=pypi)](https://pypi.org/project/agentUniverse/)
+
+![](https://github.com/alipay/agentUniverse/blob/master/docs/guidebook/_picture/logo_bar.png)
+****************************************
+
+## 项目介绍
+
+本框架是一个大模型多智能体框架。核心提供了多智能体协作编排组件，其相当于一个模式工厂（pattern factory），允许开发者对多智能体协作模式进行开发定制，同时附带了搭建单一智能体的全部关键组件。开发者可以基于本框架轻松构建多智能体应用，并通过社区对不同领域的pattern实践进行交流共享。
+
+框架将预置有若干已在真实产业中验证有效的多智能体协作模式组件，并在未来持续丰富。目前即将开放的模式组件包括：
+
+- PEER 模式组件：
+该pattern通过计划（Plan）、执行（Execute）、表达（Express）、评价（Review）四个不同职责的智能体，实现对复杂问题的多步拆解、分步执行，并基于评价反馈进行自主迭代，最终提升推理分析类任务表现。典型适用场景：事件解读、行业分析
+
+
+- DOE 模式组件：
+该pattern通过数据精制（Data-fining）、观点注入（Opinion-inject）、表达（Express）三个智能体，实现对数据密集、高计算精度、融合专家观点的生成任务的效果提升。典型适用场景：财报生成
+
+更多模式组件持续推出中...
+
+![](https://github.com/alipay/agentUniverse/blob/master/docs/guidebook/_picture/agent_universe_framework_resize.jpg)
+
+
+## agentUniverse 示例项目
+[agentUniverse 示例项目](https://github.com/alipay/agentUniverse/tree/master/sample_standard_app)
+
+## 快速安装
+使用pip：
+```shell
+pip install agentUniverse
+```
+
+## 快速开始
+我们将向您展示如何：
+* 进行环境与应用工程准备
+* 构建一个简单的agent
+* 使用模式组件完成多agent协同
+* 对agent执行效果进行测试调优
+* 对agent进行快速服务化
+
+详情请阅读[快速开始](https://github.com/alipay/agentUniverse/blob/master/docs/guidebook/zh/1_3_%E5%BF%AB%E9%80%9F%E5%BC%80%E5%A7%8B.md) 。
+
+## 用户指南
+更多详细信息，请参阅[指南](https://github.com/alipay/agentUniverse/blob/master/docs/guidebook/zh/0_%E7%9B%AE%E5%BD%95.md) 。
diff --git a/agentuniverse/agent/action/__init__.py b/agentuniverse/agent/action/__init__.py
new file mode 100644
index 00000000..749eea9f
--- /dev/null
+++ b/agentuniverse/agent/action/__init__.py
@@ -0,0 +1,7 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+
+# @Time    : 2024/4/2 17:05
+# @Author  : wangchongshi
+# @Email   : wangchongshi.wcs@antgroup.com
+# @FileName: __init__.py.py
diff --git a/agentuniverse/agent/action/knowledge/__init__.py b/agentuniverse/agent/action/knowledge/__init__.py
new file mode 100644
index 00000000..b2d5b63b
--- /dev/null
+++ b/agentuniverse/agent/action/knowledge/__init__.py
@@ -0,0 +1,7 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+
+# @Time    : 2024/4/2 17:06
+# @Author  : wangchongshi
+# @Email   : wangchongshi.wcs@antgroup.com
+# @FileName: __init__.py.py
diff --git a/agentuniverse/agent/action/knowledge/embedding/__init__.py b/agentuniverse/agent/action/knowledge/embedding/__init__.py
new file mode 100644
index 00000000..b47791e5
--- /dev/null
+++ b/agentuniverse/agent/action/knowledge/embedding/__init__.py
@@ -0,0 +1,7 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+
+# @Time    : 2024/4/2 17:07
+# @Author  : wangchongshi
+# @Email   : wangchongshi.wcs@antgroup.com
+# @FileName: __init__.py.py
diff --git a/agentuniverse/agent/action/knowledge/embedding/embedding.py b/agentuniverse/agent/action/knowledge/embedding/embedding.py
new file mode 100644
index 00000000..d9d71d50
--- /dev/null
+++ b/agentuniverse/agent/action/knowledge/embedding/embedding.py
@@ -0,0 +1,34 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+
+# @Time    : 2024/3/18 19:18
+# @Author  : wangchongshi
+# @Email   : wangchongshi.wcs@antgroup.com
+# @FileName: embedding.py
+from abc import abstractmethod
+from typing import List, Optional
+
+from pydantic import BaseModel
+from langchain_core.embeddings import Embeddings as LCEmbeddings
+
+
+class Embedding(BaseModel):
+    """The basic class for embedding.
+
+    Attributes:
+        embedding_model_name (Optional[str]): The name of the embedding model.
+    """
+
+    embedding_model_name: Optional[str] = None
+
+    @abstractmethod
+    def get_embeddings(self, text: List[str]) -> List[List[float]]:
+        """Get embeddings."""
+
+    @abstractmethod
+    async def async_get_embeddings(self, texts: List[str]) -> List[List[float]]:
+        """Asynchronously get embeddings."""
+
+    def as_langchain(self) -> LCEmbeddings:
+        """Convert the AgentUniverse(AU) embedding class to the langchain embedding class."""
+        pass
diff --git a/agentuniverse/agent/action/knowledge/embedding/openai_embedding.py b/agentuniverse/agent/action/knowledge/embedding/openai_embedding.py
new file mode 100644
index 00000000..b521577f
--- /dev/null
+++ b/agentuniverse/agent/action/knowledge/embedding/openai_embedding.py
@@ -0,0 +1,104 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+
+# @Time    : 2024/3/19 11:43
+# @Author  : wangchongshi
+# @Email   : wangchongshi.wcs@antgroup.com
+# @FileName: openai_embedding.py
+from typing import List, Optional, Any
+
+from langchain_community.embeddings.openai import OpenAIEmbeddings
+from openai import OpenAI, AsyncOpenAI, BadRequestError
+from pydantic import Field
+
+from agentuniverse.agent.action.knowledge.embedding.embedding import Embedding
+from agentuniverse.base.util.env_util import get_from_env
+
+
+class OpenAIEmbedding(Embedding):
+    """The openai embedding class."""
+
+    openai_client_args: Optional[dict] = None
+    openai_api_key: Optional[str] = Field(default_factory=lambda: get_from_env("OPENAI_API_KEY"))
+    client: Any = None
+    async_client: Any = None
+    dimensions: Optional[int] = None
+
+    def __init__(self, **kwargs):
+        """Initialize the openai embedding class."""
+        super().__init__(**kwargs)
+        if self.client is None:
+            self.client = OpenAI(api_key=self.openai_api_key, **self.openai_client_args or {})
+        if self.async_client is None:
+            self.async_client = AsyncOpenAI(api_key=self.openai_api_key, **self.openai_client_args or {})
+
+    def get_embeddings(self, texts: List[str]) -> List[List[float]]:
+        """Get the OpenAI embeddings.
+
+        Note:
+            The `embedding_model_name` parameter of the openai embedding class must be provided.
+            The `dimensions` parameter of the openai embedding class is optional.
+
+         Args:
+             texts (List[str]): A list of texts that need to be embedded.
+
+         Returns:
+             List[List[float]]: Each text gets a float list, and the result is a list of the results for each text.
+
+         Raises:
+             ValueError: If texts exceed the embedding model token limit or missing some required parameters.
+         """
+
+        if self.embedding_model_name is None:
+            raise ValueError("Must provide `embedding_model_name`")
+        try:
+            if self.dimensions:
+                response = self.client.embeddings.create(input=texts, model=self.embedding_model_name,
+                                                         dimensions=self.dimensions)
+            else:
+                response = self.client.embeddings.create(input=texts, model=self.embedding_model_name)
+
+            # Extract the embedding data from the response
+            data = response.data
+
+            # Return the embeddings as a list of lists of floats
+            return [embedding.embedding for embedding in data]
+        except BadRequestError as e:
+            raise ValueError(e.message)
+
+    async def async_get_embeddings(self, texts: List[str]) -> List[List[float]]:
+        """Asynchronously get the OpenAI embeddings.
+
+        Note:
+            The `embedding_model_name` parameter of the openai embedding class must be provided.
+            The `dimensions` parameter of the openai embedding class is optional.
+
+         Args:
+             texts (List[str]): A list of texts that need to be embedded.
+
+         Returns:
+             List[List[float]]: Each text gets a float list, and the result is a list of the results for each text.
+         Raises:
+             ValueError: If texts exceed the embedding model token limit or missing some required parameters.
+         """
+
+        if self.embedding_model_name is None:
+            raise ValueError("Must provide `embedding_model_name`")
+        try:
+            if self.dimensions:
+                response = await self.async_client.embeddings.create(input=texts, model=self.embedding_model_name,
+                                                                     dimensions=self.dimensions)
+            else:
+                response = await self.async_client.embeddings.create(input=texts, model=self.embedding_model_name)
+            # Extract the embedding data from the response
+            data = response.data
+
+            # Return the embeddings as a list of lists of floats
+            return [embedding.embedding for embedding in data]
+        except BadRequestError as e:
+            raise ValueError(e.message)
+
+    def as_langchain(self) -> OpenAIEmbeddings:
+        """Convert the AgentUniverse(AU) openai embedding class to the langchain openai embedding class."""
+        return OpenAIEmbeddings(openai_api_key=self.openai_api_key,
+                                client=self.client.embeddings, async_client=self.async_client.embeddings)
diff --git a/agentuniverse/agent/action/knowledge/knowledge.py b/agentuniverse/agent/action/knowledge/knowledge.py
new file mode 100644
index 00000000..f8e631a7
--- /dev/null
+++ b/agentuniverse/agent/action/knowledge/knowledge.py
@@ -0,0 +1,79 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+
+# @Time    : 2024/3/22 15:44
+# @Author  : wangchongshi
+# @Email   : wangchongshi.wcs@antgroup.com
+# @FileName: knowledge.py
+from typing import Optional, Dict, List, Any
+
+from agentuniverse.agent.action.knowledge.reader.reader import Reader
+from agentuniverse.agent.action.knowledge.store.document import Document
+from agentuniverse.agent.action.knowledge.store.query import Query
+from agentuniverse.agent.action.knowledge.store.store import Store
+from agentuniverse.base.component.component_base import ComponentBase
+from agentuniverse.base.component.component_enum import ComponentEnum
+from agentuniverse.base.config.application_configer.application_config_manager import ApplicationConfigManager
+from agentuniverse.base.config.component_configer.configers.knowledge_configer import KnowledgeConfiger
+
+
+class Knowledge(ComponentBase):
+    """The basic class for knowledge model.
+
+    Attributes:
+        name (str): The name of the knowledge.
+
+        description (str): The description of the knowledge.
+
+        store (Store): The store of the knowledge, which is used to store knowledge
+            and provide retrieval capabilities, such as ChromaDB store or Redis Store.
+
+        reader (Reader): The reader of the knowledge, which is used to load data and generate knowledge.
+
+        ext_info (Optional[Dict]): The extended information of the knowledge.
+    """
+
+    name: str = ""
+    description: Optional[str] = None
+    store: Store = None
+    reader: Reader = None
+    ext_info: Optional[Dict] = None
+
+    def __init__(self, **kwargs):
+        super().__init__(component_type=ComponentEnum.KNOWLEDGE, **kwargs)
+
+    def insert_knowledge(self, **kwargs) -> None:
+        """Insert the knowledge.
+
+        Load data by the reader and insert the documents into the store.
+        """
+        document_list: List[Document] = self.reader.load_data()
+        self.store.insert_documents(document_list, **kwargs)
+
+    def query_knowledge(self, **kwargs) -> List[Document]:
+        """Query the knowledge.
+
+        Query documents from the store and return the results.
+        """
+        query = Query(**kwargs)
+        return self.store.query(query)
+
+    def get_instance_code(self) -> str:
+        """Return the full name of the knowledge."""
+        appname = ApplicationConfigManager().app_configer.base_info_appname
+        return f'{appname}.{self.component_type.value.lower()}.{self.name}'
+
+    def initialize_by_component_configer(self, component_configer: KnowledgeConfiger) -> 'Knowledge':
+        """Initialize the Knowledge by the ComponentConfiger object.
+        Args:
+            component_configer(KnowledgeConfiger): the ComponentConfiger object
+        Returns:
+            Knowledge: the Knowledge object
+        """
+        if component_configer.name:
+            self.name = component_configer.name
+        if component_configer.description:
+            self.description = component_configer.description
+        if component_configer.ext_info:
+            self.ext_info = component_configer.ext_info
+        return self
diff --git a/agentuniverse/agent/action/knowledge/knowledge_manager.py b/agentuniverse/agent/action/knowledge/knowledge_manager.py
new file mode 100644
index 00000000..21b345a3
--- /dev/null
+++ b/agentuniverse/agent/action/knowledge/knowledge_manager.py
@@ -0,0 +1,19 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+
+# @Time    : 2024/3/18 11:24
+# @Author  : wangchongshi
+# @Email   : wangchongshi.wcs@antgroup.com
+# @FileName: knowledge_manager.py
+from agentuniverse.base.annotation.singleton import singleton
+from agentuniverse.base.component.component_enum import ComponentEnum
+from agentuniverse.base.component.component_manager_base import ComponentManagerBase
+
+
+@singleton
+class KnowledgeManager(ComponentManagerBase):
+    """The KnowledgeManager class, which is used to manage the knowledge."""
+
+    def __init__(self):
+        """Initialize the KnowledgeManager."""
+        super().__init__(ComponentEnum.KNOWLEDGE)
diff --git a/agentuniverse/agent/action/knowledge/reader/__init__.py b/agentuniverse/agent/action/knowledge/reader/__init__.py
new file mode 100644
index 00000000..1787928f
--- /dev/null
+++ b/agentuniverse/agent/action/knowledge/reader/__init__.py
@@ -0,0 +1,7 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+
+# @Time    : 2024/4/2 17:13
+# @Author  : wangchongshi
+# @Email   : wangchongshi.wcs@antgroup.com
+# @FileName: __init__.py.py
diff --git a/agentuniverse/agent/action/knowledge/reader/file/__init__.py b/agentuniverse/agent/action/knowledge/reader/file/__init__.py
new file mode 100644
index 00000000..1787928f
--- /dev/null
+++ b/agentuniverse/agent/action/knowledge/reader/file/__init__.py
@@ -0,0 +1,7 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+
+# @Time    : 2024/4/2 17:13
+# @Author  : wangchongshi
+# @Email   : wangchongshi.wcs@antgroup.com
+# @FileName: __init__.py.py
diff --git a/agentuniverse/agent/action/knowledge/reader/file/docx_reader.py b/agentuniverse/agent/action/knowledge/reader/file/docx_reader.py
new file mode 100644
index 00000000..07ba7e1a
--- /dev/null
+++ b/agentuniverse/agent/action/knowledge/reader/file/docx_reader.py
@@ -0,0 +1,38 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+
+# @Time    : 2024/3/18 14:32
+# @Author  : wangchongshi
+# @Email   : wangchongshi.wcs@antgroup.com
+# @FileName: doc_parser.py
+from pathlib import Path
+from typing import List, Optional, Dict
+
+from agentuniverse.agent.action.knowledge.reader.reader import Reader
+from agentuniverse.agent.action.knowledge.store.document import Document
+
+
+class DocxReader(Reader):
+    """Docx reader."""
+
+    def load_data(self, file: Path, ext_info: Optional[Dict] = None) -> List[Document]:
+        """Parse the docx file.
+
+        Note:
+            The docx file cannot be process in pagination.
+            `docx2txt` is required to read DOCX files: `pip install docx2txt`
+        """
+        try:
+            import docx2txt
+        except ImportError:
+            raise ImportError(
+                "docx2txt is required to read Microsoft Word files: "
+                "`pip install docx2txt`"
+            )
+
+        text = docx2txt.process(file)
+        metadata = {"file_name": file.name}
+        if ext_info is not None:
+            metadata.update(ext_info)
+
+        return [Document(text=text, metadata=metadata or {})]
diff --git a/agentuniverse/agent/action/knowledge/reader/file/file_reader.py b/agentuniverse/agent/action/knowledge/reader/file/file_reader.py
new file mode 100644
index 00000000..3c950201
--- /dev/null
+++ b/agentuniverse/agent/action/knowledge/reader/file/file_reader.py
@@ -0,0 +1,43 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+
+# @Time    : 2024/3/22 14:49
+# @Author  : wangchongshi
+# @Email   : wangchongshi.wcs@antgroup.com
+# @FileName: file_reader.py
+from pathlib import Path
+from typing import Dict, Type, List, Optional
+
+from agentuniverse.agent.action.knowledge.reader.file.docx_reader import DocxReader
+from agentuniverse.agent.action.knowledge.reader.file.pdf_reader import PdfReader
+from agentuniverse.agent.action.knowledge.reader.file.pptx_reader import PptxReader
+from agentuniverse.agent.action.knowledge.reader.reader import Reader
+from agentuniverse.agent.action.knowledge.store.document import Document
+
+DEFAULT_FILE_READERS: Dict[str, Type[Reader]] = {
+    ".pdf": PdfReader,
+    ".docx": DocxReader,
+    ".pptx": PptxReader,
+}
+
+
+class FileReader(Reader):
+    """The AgentUniverse(AU) file reader class.
+
+    FileReader is used to load data from files based on the provided file paths.
+
+    Attributes:
+        file_readers (Dict[str, Type[Reader]], optional): The file reader dictionary,
+        the key is the suffix of the file, and the value is the specific file reader class.
+    """
+
+    file_readers: Dict[str, Type[Reader]] = DEFAULT_FILE_READERS
+
+    def load_data(self, file_paths: List[Path], ext_info: Optional[Dict] = None) -> List[Document]:
+        document_list = []
+        for file_path in file_paths:
+            file_suffix = file_path.suffix.lower()
+            if file_suffix in self.file_readers.keys():
+                file_reader = self.file_readers[file_suffix]()
+                document_list.extend(file_reader.load_data(file=file_path, ext_info=ext_info))
+        return document_list
diff --git a/agentuniverse/agent/action/knowledge/reader/file/pdf_reader.py b/agentuniverse/agent/action/knowledge/reader/file/pdf_reader.py
new file mode 100644
index 00000000..e9215f41
--- /dev/null
+++ b/agentuniverse/agent/action/knowledge/reader/file/pdf_reader.py
@@ -0,0 +1,49 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+
+# @Time    : 2024/3/18 14:21
+# @Author  : wangchongshi
+# @Email   : wangchongshi.wcs@antgroup.com
+# @FileName: pdf_parser.py
+from pathlib import Path
+from typing import List, Optional, Dict
+
+from agentuniverse.agent.action.knowledge.reader.reader import Reader
+from agentuniverse.agent.action.knowledge.store.document import Document
+
+
+class PdfReader(Reader):
+    """PDF reader."""
+
+    def load_data(self, file: Path, ext_info: Optional[Dict] = None) -> List[Document]:
+        """Parse the pdf file.
+
+        Note:
+            `pypdf` is required to read PDF files: `pip install pypdf`
+        """
+        try:
+            import pypdf
+        except ImportError:
+            raise ImportError(
+                "pypdf is required to read PDF files: `pip install pypdf`"
+            )
+        with open(file, "rb") as fp:
+            # Create a PDF object
+            pdf = pypdf.PdfReader(fp)
+
+            # Get the number of pages in the PDF document
+            num_pages = len(pdf.pages)
+
+            # Iterate over every page
+            docs = []
+            for page in range(num_pages):
+                # Extract the text from the page
+                page_text = pdf.pages[page].extract_text()
+                page_label = pdf.page_labels[page]
+
+                metadata = {"page_label": page_label, "file_name": file.name}
+                if ext_info is not None:
+                    metadata.update(ext_info)
+
+                docs.append(Document(text=page_text, metadata=metadata))
+            return docs
diff --git a/agentuniverse/agent/action/knowledge/reader/file/pptx_reader.py b/agentuniverse/agent/action/knowledge/reader/file/pptx_reader.py
new file mode 100644
index 00000000..a1e609cc
--- /dev/null
+++ b/agentuniverse/agent/action/knowledge/reader/file/pptx_reader.py
@@ -0,0 +1,40 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+
+# @Time    : 2024/3/18 17:34
+# @Author  : wangchongshi
+# @Email   : wangchongshi.wcs@antgroup.com
+# @FileName: pptx_parser.py
+from pathlib import Path
+from typing import Dict, List, Optional
+
+from agentuniverse.agent.action.knowledge.reader.reader import Reader
+from agentuniverse.agent.action.knowledge.store.document import Document
+
+
+class PptxReader(Reader):
+    """Pptx reader."""
+
+    def load_data(self, file: Path, ext_info: Optional[Dict] = None) -> List[Document]:
+        """Parse the pptx file.
+
+        Note:
+            `python-pptx` is required to read PPTX files: `pip install python-pptx`
+        """
+        try:
+            from pptx import Presentation
+        except ImportError:
+            raise ImportError(
+                "python-pptx is required to read pptx files: `pip install python-pptx`"
+            )
+        presentation = Presentation(file)
+        document_list = []
+        for slide_number, slide in enumerate(presentation.slides, start=1):
+            for shape in slide.shapes:
+                if hasattr(shape, "text"):
+                    metadata = {"slide_number": slide_number, "file_name": file.name}
+                    if ext_info is not None:
+                        metadata.update(ext_info)
+                    # Extract the text from the shape
+                    document_list.append(Document(text=shape.text, metadata=metadata))
+        return document_list
diff --git a/agentuniverse/agent/action/knowledge/reader/file/web_pdf_reader.py b/agentuniverse/agent/action/knowledge/reader/file/web_pdf_reader.py
new file mode 100644
index 00000000..efd551cb
--- /dev/null
+++ b/agentuniverse/agent/action/knowledge/reader/file/web_pdf_reader.py
@@ -0,0 +1,39 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+
+# @Time    : 2024/3/31 14:25
+# @Author  : wangchongshi
+# @Email   : wangchongshi.wcs@antgroup.com
+# @FileName: web_pdf_reader.py
+from io import BytesIO
+from typing import List
+import requests
+
+from agentuniverse.agent.action.knowledge.reader.reader import Reader
+from agentuniverse.agent.action.knowledge.store.document import Document
+
+
+class WebPdfReader(Reader):
+    """The AgentUniverse(AU) web pdf reader.
+
+    The pdf file will be downloaded and then parsed by `pdfminer.six`.
+    """
+
+    def load_data(self, web_pdf_url: str) -> List[Document]:
+        if web_pdf_url is None:
+            return []
+        response = requests.get(web_pdf_url)
+        if response.status_code == 200:
+            # download the pdf file and convert it into a memory file.
+            pdf_memory_file = BytesIO(response.content)
+            try:
+                from pdfminer.high_level import extract_text_to_fp
+            except ImportError:
+                raise ImportError(
+                    "pdfminer.six is required to read PDF files: `pip install pdfminer.six`"
+                )
+            # parse the pdf file and get the text content.
+            with BytesIO() as output_string:
+                extract_text_to_fp(pdf_memory_file, output_string, output_type='text', codec='utf-8')
+                text = output_string.getvalue().decode('utf-8')
+                return [Document(text=text, metadata={"source": web_pdf_url})]
diff --git a/agentuniverse/agent/action/knowledge/reader/reader.py b/agentuniverse/agent/action/knowledge/reader/reader.py
new file mode 100644
index 00000000..edd1ba75
--- /dev/null
+++ b/agentuniverse/agent/action/knowledge/reader/reader.py
@@ -0,0 +1,21 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+
+# @Time    : 2024/3/22 14:30
+# @Author  : wangchongshi
+# @Email   : wangchongshi.wcs@antgroup.com
+# @FileName: reader.py
+from abc import abstractmethod
+from typing import List, Any
+
+from pydantic import BaseModel
+
+from agentuniverse.agent.action.knowledge.store.document import Document
+
+
+class Reader(BaseModel):
+    """The basic class for the knowledge reader."""
+
+    @abstractmethod
+    def load_data(self, *args: Any, **kwargs: Any) -> List[Document]:
+        """Load data from the input params."""
diff --git a/agentuniverse/agent/action/knowledge/store/__init__.py b/agentuniverse/agent/action/knowledge/store/__init__.py
new file mode 100644
index 00000000..a48f6ff5
--- /dev/null
+++ b/agentuniverse/agent/action/knowledge/store/__init__.py
@@ -0,0 +1,7 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+
+# @Time    : 2024/4/2 17:17
+# @Author  : wangchongshi
+# @Email   : wangchongshi.wcs@antgroup.com
+# @FileName: __init__.py.py
diff --git a/agentuniverse/agent/action/knowledge/store/chroma_store.py b/agentuniverse/agent/action/knowledge/store/chroma_store.py
new file mode 100644
index 00000000..cda4405a
--- /dev/null
+++ b/agentuniverse/agent/action/knowledge/store/chroma_store.py
@@ -0,0 +1,116 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+
+# @Time    : 2024/3/22 16:31
+# @Author  : wangchongshi
+# @Email   : wangchongshi.wcs@antgroup.com
+# @FileName: chroma_store.py
+from typing import List, Any, Optional
+
+import chromadb
+from chromadb import QueryResult
+from chromadb.api.models import Collection
+
+from agentuniverse.agent.action.knowledge.store.document import Document
+from agentuniverse.agent.action.knowledge.store.query import Query
+from agentuniverse.agent.action.knowledge.store.store import Store
+
+
+class ChromaStore(Store):
+    """Object encapsulating the ChromaDB store that has vector search enabled.
+
+    The ChromaStore object provides insert and retrieval capabilities.
+
+    Attributes:
+        collection_name (str): The name of the chroma collection to use.
+        collection (Collection): A chroma collection object.
+        persist_path (Optional[str]): Path to save the chroma database.
+    """
+
+    collection_name: Optional[str] = 'chroma_db'
+    collection: Collection = None
+    persist_path: Optional[str] = None
+
+    def __init__(self, **kwargs):
+        """Initialize the chroma store class."""
+        super().__init__(**kwargs)
+        if self.collection is None:
+            # default to create a new collection or get an existed collection.
+            self.collection = self.client.get_or_create_collection(name=self.collection_name)
+
+    def _new_client(self) -> Any:
+        """Initialize the chroma client."""
+        if self.persist_path is None:
+            return chromadb.PersistentClient()
+        else:
+            return chromadb.PersistentClient(path=self.persist_path)
+
+    def query(self, query: Query, **kwargs) -> List[Document]:
+        """Query the chroma collection with the given query and return the top k results.
+
+        Args:
+            query (Query): The query object.
+            **kwargs: Arbitrary keyword arguments.
+
+        Note:
+            If there is no embedding in the specific query, but the embedding model is configured in the store,
+            the embedding data of the query is automatically obtained by the embedding model.
+
+        Returns:
+            List[Document]: List of documents retrieved by the query.
+        """
+
+        embedding = query.embedding
+        if self.embedding_model is not None and len(embedding) == 0:
+            embedding = self.embedding_model.get_embeddings([query.query_str])[0]
+        if len(embedding) > 0:
+            query_result = self.collection.query(
+                n_results=query.similarity_top_k,
+                query_embeddings=[embedding]
+            )
+        else:
+            query_result = self.collection.query(
+                n_results=query.similarity_top_k,
+                query_texts=[query.query_str]
+            )
+        # convert to the AgentUniverse(AU) document format
+        return self.to_documents(query_result)
+
+    def insert_documents(self, documents: List[Document], **kwargs: Any):
+        """Insert documents to the chroma collection.
+
+        Args:
+            documents (List[Document]): The documents to be inserted.
+            **kwargs: Arbitrary keyword arguments.
+
+        Note:
+            If there is no embedding in the specific document, but the embedding model is configured in the store,
+            the embedding data of the document is automatically obtained by the embedding model.
+        """
+
+        for document in documents:
+            embedding = document.embedding
+            if self.embedding_model is not None and len(embedding) == 0:
+                embedding = self.embedding_model.get_embeddings([document.text])[0]
+            self.collection.add(
+                documents=[document.text],
+                metadatas=[document.metadata],
+                embeddings=[embedding] if embedding is not None else None,
+                ids=[document.id]
+            )
+
+    @staticmethod
+    def to_documents(query_result: QueryResult) -> List[Document]:
+        """Convert the query results of ChromaDB to the AgentUniverse(AU) document format."""
+
+        if query_result is None:
+            return []
+        documents = []
+        for i in range(len(query_result['ids'][0])):
+            documents.append(Document(id=query_result['ids'][0][i],
+                                      text=query_result['documents'][0][i],
+                                      embedding=query_result['embeddings'][0][i]
+                                      if query_result['embeddings'] is not None else [],
+                                      metadata=query_result['metadatas'][0][i]
+                                      if query_result['metadatas'] is not None else None))
+        return documents
diff --git a/agentuniverse/agent/action/knowledge/store/document.py b/agentuniverse/agent/action/knowledge/store/document.py
new file mode 100644
index 00000000..46ef5896
--- /dev/null
+++ b/agentuniverse/agent/action/knowledge/store/document.py
@@ -0,0 +1,52 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+# @Time    : 2024/3/19 19:19
+# @Author  : wangchongshi
+# @Email   : wangchongshi.wcs@antgroup.com
+# @FileName: document.py
+import uuid
+from typing import Dict, Any, Optional, List
+
+from langchain_core.documents.base import Document as LCDocument
+from pydantic import BaseModel, Field
+
+
+class Document(BaseModel):
+    """The basic class for the document.
+
+    Attributes:
+        id (str): Unique identifier for the document.
+        text (Optional[str]): The content of the document.
+        metadata (Dict[str, Any]): Metadata associated with the document.
+        embedding (List[float]): Embedding data associated with the document
+    """
+
+    id: str = Field(default_factory=lambda: str(uuid.uuid4()))
+    text: Optional[str] = ""
+    metadata: Optional[Dict[str, Any]] = None
+    embedding: List[float] = Field(default_factory=list)
+
+    def as_langchain(self) -> LCDocument:
+        """Convert to LangChain document format."""
+        metadata = self.metadata or {}
+        return LCDocument(page_content=self.text, metadata=metadata)
+
+    @staticmethod
+    def as_langchain_list(document_list) -> List[LCDocument]:
+        """Convert AgentUniverse(AU) document list to langchain document list """
+        langchain_document_list = []
+        if document_list is None:
+            return langchain_document_list
+        for document in document_list:
+            langchain_document_list.append(LCDocument(page_content=document.text, metadata=document.metadata))
+        return langchain_document_list
+
+    @staticmethod
+    def from_langchain_list(lc_document_list: List[LCDocument]):
+        """Convert langchain document list to AgentUniverse(AU) document list """
+        document_list = []
+        if lc_document_list is None:
+            return document_list
+        for lc_document in lc_document_list:
+            document_list.append(Document(text=lc_document.page_content, metadata=lc_document.metadata))
+        return document_list
diff --git a/agentuniverse/agent/action/knowledge/store/query.py b/agentuniverse/agent/action/knowledge/store/query.py
new file mode 100644
index 00000000..aa2d2ce5
--- /dev/null
+++ b/agentuniverse/agent/action/knowledge/store/query.py
@@ -0,0 +1,25 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+
+# @Time    : 2024/3/22 15:52
+# @Author  : wangchongshi
+# @Email   : wangchongshi.wcs@antgroup.com
+# @FileName: query.py
+
+from typing import Optional, List
+
+from pydantic import BaseModel, Field
+
+
+class Query(BaseModel):
+    """The basic class for the knowledge query.
+
+    Attributes:
+        query_str (Optional[str]): The query string.
+        similarity_top_k (int): The number of top results to return.
+        embedding (List[float]): The specific embedding data of the query.
+    """
+
+    query_str: Optional[str] = None
+    similarity_top_k: int = 2
+    embedding: List[float] = Field(default_factory=list)
diff --git a/agentuniverse/agent/action/knowledge/store/store.py b/agentuniverse/agent/action/knowledge/store/store.py
new file mode 100644
index 00000000..8be62a52
--- /dev/null
+++ b/agentuniverse/agent/action/knowledge/store/store.py
@@ -0,0 +1,89 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+
+# @Time    : 2024/3/22 15:50
+# @Author  : wangchongshi
+# @Email   : wangchongshi.wcs@antgroup.com
+# @FileName: store.py
+from typing import Any, List, Optional
+from pydantic import BaseModel
+
+from agentuniverse.agent.action.knowledge.embedding.embedding import Embedding
+from agentuniverse.agent.action.knowledge.store.document import Document
+from agentuniverse.agent.action.knowledge.store.query import Query
+
+
+class Store(BaseModel):
+    """The basic class for the knowledge store.
+
+    Store of the knowledge, store class is used to store knowledge
+    and provide retrieval capabilities,
+    vector storage, such as ChromaDB store, or non-vector storage, such as Redis Store.
+
+    Attributes:
+        client (Any): The client of the store,
+        client is usually used to connect to the storage and provides knowledge insertion,
+        update, deletion, and query operations
+
+        async_client (Any): The async client of the store,
+        the function is the same as that of the `client` parameter  in asynchronous mode.
+
+        embedding_model (Embedding): The embedding model of the store,
+        used to provided embedding operations on texts to generate a list of floats.
+    """
+
+    client: Any = None
+    async_client: Any = None
+    embedding_model: Optional[Embedding] = None
+
+    class Config:
+        """Configuration for this pydantic object."""
+        arbitrary_types_allowed = True
+
+    def __init__(self, **kwargs):
+        """Initialize the store class."""
+        super().__init__(**kwargs)
+        if self.client is None:
+            self.client = self._new_client()
+        if self.async_client is None:
+            self.async_client = self._new_async_client()
+
+    def _new_client(self) -> Any:
+        """Initialize the client."""
+        pass
+
+    def _new_async_client(self) -> Any:
+        """Initialize the async client."""
+        pass
+
+    def query(self, query: Query, **kwargs) -> List[Document]:
+        """Query documents."""
+        raise NotImplementedError
+
+    async def async_query(self, query: Query, **kwargs) -> List[Document]:
+        """Asynchronously query documents."""
+        raise NotImplementedError
+
+    def insert_documents(self, documents: List[Document], **kwargs):
+        """Insert documents into the store."""
+        raise NotImplementedError
+
+    async def async_insert_documents(self, documents: List[Document], **kwargs):
+        """Asynchronously insert documents into the store."""
+        raise NotImplementedError
+
+    def insert_document(self, document: Document, **kwargs):
+        """Insert document into the store."""
+        raise NotImplementedError
+
+    async def async_insert_document(self, document: Document, **kwargs):
+        """Asynchronously insert document into the store."""
+        raise NotImplementedError
+
+    def delete_document(self, document_id: str, **kwargs):
+        """Delete the specific document by the document id."""
+        raise NotImplementedError
+
+    async def async_delete_document(self, document_id: str, **kwargs):
+        """Asynchronously delete the specific document by the document id."""
+        raise NotImplementedError
diff --git a/agentuniverse/agent/action/tool/__init__.py b/agentuniverse/agent/action/tool/__init__.py
new file mode 100644
index 00000000..b2d5b63b
--- /dev/null
+++ b/agentuniverse/agent/action/tool/__init__.py
@@ -0,0 +1,7 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+
+# @Time    : 2024/4/2 17:06
+# @Author  : wangchongshi
+# @Email   : wangchongshi.wcs@antgroup.com
+# @FileName: __init__.py.py
diff --git a/agentuniverse/agent/action/tool/enum.py b/agentuniverse/agent/action/tool/enum.py
new file mode 100644
index 00000000..f59d72a8
--- /dev/null
+++ b/agentuniverse/agent/action/tool/enum.py
@@ -0,0 +1,15 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+
+# @Time    : 2024/3/13 14:34
+# @Author  : wangchongshi
+# @Email   : wangchongshi.wcs@antgroup.com
+# @FileName: enum.py
+import enum
+from enum import Enum
+
+
+@enum.unique
+class ToolTypeEnum(Enum):
+    API = 'api'
+    FUNC = 'func'
diff --git a/agentuniverse/agent/action/tool/tool.py b/agentuniverse/agent/action/tool/tool.py
new file mode 100644
index 00000000..bb53cc49
--- /dev/null
+++ b/agentuniverse/agent/action/tool/tool.py
@@ -0,0 +1,106 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+
+# @Time    : 2024/3/13 14:29
+# @Author  : wangchongshi
+# @Email   : wangchongshi.wcs@antgroup.com
+# @FileName: tool.py
+from abc import abstractmethod
+import json
+from typing import List, Optional
+
+from pydantic import BaseModel
+from langchain.tools import Tool as LangchainTool
+
+from agentuniverse.agent.action.tool.enum import ToolTypeEnum
+from agentuniverse.base.component.component_base import ComponentBase
+from agentuniverse.base.component.component_enum import ComponentEnum
+from agentuniverse.base.config.application_configer.application_config_manager import ApplicationConfigManager
+from agentuniverse.base.config.component_configer.configers.tool_configer import ToolConfiger
+
+
+class ToolInput(BaseModel):
+    """The basic class for tool input."""
+
+    def __init__(self, params: dict, **kwargs):
+        super().__init__(**kwargs)
+        self.__origin_params = params
+        for k, v in params.items():
+            self.__dict__[k] = v
+
+    def to_dict(self):
+        return self.__origin_params
+
+    def to_json_str(self):
+        return json.dumps(self.__origin_params, ensure_ascii=False)
+
+    def add_data(self, key, value):
+        self.__origin_params[key] = value
+        self.__dict__[key] = value
+
+    def get_data(self, key, default=None):
+        return self.__origin_params.get(key, default)
+
+
+class Tool(ComponentBase):
+    """
+    The basic class for tool model.
+
+    Attributes:
+        name (str): The name of the tool.
+        description (str): The description of the tool.
+        tool_type (ToolTypeEnum): The type of the tool.
+        input_keys (Optional[List]): The input keys of the tool, e.g. ['input1', 'input2']
+    """
+
+    name: str = ""
+    description: Optional[str] = None
+    tool_type: ToolTypeEnum = ToolTypeEnum.FUNC
+    input_keys: Optional[List] = None
+
+    def __init__(self, **kwargs):
+        super().__init__(component_type=ComponentEnum.TOOL, **kwargs)
+
+    def run(self, **kwargs):
+        """The callable method that runs the tool."""
+        self.input_check(kwargs)
+        tool_input = ToolInput(kwargs)
+        return self.execute(tool_input)
+
+    def input_check(self, kwargs: dict) -> None:
+        """Check whether the input parameters of the tool contain input keys of the tool"""
+        for key in self.input_keys:
+            if key not in kwargs.keys():
+                raise Exception(f'{self.get_instance_code()} - The input must include key: {key}.')
+
+    @abstractmethod
+    def execute(self, tool_input: ToolInput):
+        raise NotImplementedError
+
+    def as_langchain(self) -> LangchainTool:
+        """Convert the AgentUniverse(AU) tool class to the langchain tool class."""
+        return LangchainTool(name=self.name,
+                             func=self.run,
+                             description=self.description)
+
+    def get_instance_code(self) -> str:
+        """Return the full name of the tool."""
+        appname = ApplicationConfigManager().app_configer.base_info_appname
+        return f'{appname}.{self.component_type.value.lower()}.{self.name}'
+
+    def initialize_by_component_configer(self, component_configer: ToolConfiger) -> 'Tool':
+        """Initialize the LLM by the ComponentConfiger object.
+        Args:
+            component_configer(LLMConfiger): the ComponentConfiger object
+        Returns:
+            LLM: the LLM object
+        """
+        if component_configer.name:
+            self.name = component_configer.name
+        if component_configer.description:
+            self.description = component_configer.description
+        if component_configer.tool_type:
+            self.tool_type = next((member for member in ToolTypeEnum if member.value == component_configer.tool_type))
+        if component_configer.input_keys:
+            self.input_keys = component_configer.input_keys
+        return self
diff --git a/agentuniverse/agent/action/tool/tool_manager.py b/agentuniverse/agent/action/tool/tool_manager.py
new file mode 100644
index 00000000..58bb674b
--- /dev/null
+++ b/agentuniverse/agent/action/tool/tool_manager.py
@@ -0,0 +1,19 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+
+# @Time    : 2024/3/13 13:54
+# @Author  : wangchongshi
+# @Email   : wangchongshi.wcs@antgroup.com
+# @FileName: tool_manager.py
+from agentuniverse.base.annotation.singleton import singleton
+from agentuniverse.base.component.component_enum import ComponentEnum
+from agentuniverse.base.component.component_manager_base import ComponentManagerBase
+
+
+@singleton
+class ToolManager(ComponentManagerBase):
+    """The ToolManager class, which is used to manage the tools."""
+
+    def __init__(self):
+        """Initialize the ToolManager."""
+        super().__init__(ComponentEnum.TOOL)
diff --git a/agentuniverse/agent/agent.py b/agentuniverse/agent/agent.py
new file mode 100644
index 00000000..fdf8bc3d
--- /dev/null
+++ b/agentuniverse/agent/agent.py
@@ -0,0 +1,149 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+
+# @Time    : 2024/3/12 19:36
+# @Author  : heji
+# @Email   : lc299034@antgroup.com
+# @FileName: agent.py
+"""The definition of agent paradigm."""
+from abc import abstractmethod
+from typing import Optional
+
+from agentuniverse.agent.agent_model import AgentModel
+from agentuniverse.agent.input_object import InputObject
+from agentuniverse.agent.output_object import OutputObject
+from agentuniverse.agent.plan.planner.planner import Planner
+from agentuniverse.agent.plan.planner.planner_manager import PlannerManager
+from agentuniverse.base.component.component_base import ComponentBase
+from agentuniverse.base.component.component_enum import ComponentEnum
+from agentuniverse.base.config.application_configer.application_config_manager \
+    import ApplicationConfigManager
+from agentuniverse.base.config.component_configer.configers.agent_configer \
+    import AgentConfiger
+from agentuniverse.llm.llm import LLM
+
+
+class Agent(ComponentBase):
+    """The parent class of all agent models, containing only attributes."""
+
+    agent_model: Optional[AgentModel] = None
+
+    def __init__(self):
+        """Initialize the AgentModel with the given keyword arguments."""
+        super().__init__(component_type=ComponentEnum.AGENT)
+
+    @abstractmethod
+    def input_keys(self) -> list[str]:
+        """Return the input keys of the Agent."""
+        pass
+
+    @abstractmethod
+    def output_keys(self) -> list[str]:
+        """Return the output keys of the Agent."""
+        pass
+
+    @abstractmethod
+    def parse_input(self, input_object: InputObject, planner_input: dict) -> dict:
+        """Planner parameter parsing.
+
+        Args:
+            input_object(InputObject): agent parameter object
+            planner_input(dict): Planner input
+        Returns:
+            dict: Planner parameter.
+        """
+        pass
+
+    @abstractmethod
+    def parse_result(self, planner_result: dict) -> dict:
+        """Planner result parser.
+
+        Args:
+            planner_result(dict): Planner result
+        Returns:
+            dict: Agent result object.
+        """
+        pass
+
+    def run(self, **kwargs) -> OutputObject:
+        """Agent instance running entry.
+
+        Returns:
+            OutputObject: Agent execution result
+        """
+        self.input_check(kwargs)
+        input_object = InputObject(kwargs)
+        execute_result = self.execute(input_object)
+        self.output_check(execute_result)
+        output_object = OutputObject(execute_result)
+        return output_object
+
+    def execute(self, input_object: InputObject) -> dict:
+        """Execute agent instance.
+
+        Args:
+            input_object(InputObject): agent parameter object
+        Returns:
+            dict: Agent result object.
+        """
+        planner_input = self.pre_parse_input(input_object)
+
+        planner_base: Planner = PlannerManager().get_instance_obj(self.agent_model.plan.get('planner').get('name'))
+        planner_result = planner_base.invoke(self.agent_model, planner_input, input_object)
+
+        parser_result = self.parse_result(planner_result)
+        return parser_result
+
+    def pre_parse_input(self, input_object) -> dict:
+        """Agent execution parameter pre-parsing.
+
+        Args: input_object(InputObject): agent parameter object
+        Returns:
+            dict: Planner input
+        """
+        planner_input = dict()
+        planner_input['chat_history'] = input_object.get_data('chat_history') or ''
+        planner_input['background'] = input_object.get_data('background') or ''
+
+        self.parse_input(input_object, planner_input)
+        return planner_input
+
+    def get_instance_code(self) -> str:
+        """Return the full name of the agent."""
+        appname = ApplicationConfigManager().app_configer.base_info_appname
+        name = self.agent_model.info.get('name')
+        return (f'{appname}.'
+                f'{self.component_type.value.lower()}.{name}')
+
+    def input_check(self, kwargs: dict):
+        """Agent parameter check."""
+        for key in self.input_keys():
+            if key not in kwargs.keys():
+                raise Exception(f'Input must have key: {key}.')
+
+    def output_check(self, kwargs: dict):
+        """Agent result check."""
+        if not isinstance(kwargs, dict):
+            raise Exception('Output type must be dict.')
+        for key in self.output_keys():
+            if key not in kwargs.keys():
+                raise Exception(f'Output must have key: {key}.')
+
+    def initialize_by_component_configer(self, component_configer: AgentConfiger) -> 'Agent':
+        """Initialize the LLM by the ComponentConfiger object.
+
+        Args:
+            component_configer(LLMConfiger): the ComponentConfiger object
+        Returns:
+            LLM: the LLM object
+        """
+        agent_config: Optional[AgentConfiger] = component_configer.load()
+        info: Optional[dict] = agent_config.info
+        profile: Optional[dict] = agent_config.profile
+        plan: Optional[dict] = agent_config.plan
+        memory: Optional[dict] = agent_config.memory
+        action: Optional[dict] = agent_config.action
+        agent_model: Optional[AgentModel] = AgentModel(info=info, profile=profile,
+                                                       plan=plan, memory=memory, action=action)
+        self.agent_model = agent_model
+        return self
diff --git a/agentuniverse/agent/agent_manager.py b/agentuniverse/agent/agent_manager.py
new file mode 100644
index 00000000..671b492e
--- /dev/null
+++ b/agentuniverse/agent/agent_manager.py
@@ -0,0 +1,20 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+# @Time    : 2024/3/12 20:02
+# @Author  : heji
+# @Email   : lc299034@antgroup.com
+# @FileName: agent_manager.py
+
+"""Agents manager."""
+from agentuniverse.base.annotation.singleton import singleton
+from agentuniverse.base.component.component_enum import ComponentEnum
+from agentuniverse.base.component.component_manager_base import ComponentManagerBase
+
+
+@singleton
+class AgentManager(ComponentManagerBase):
+    """The AgentManager class, which is used to manage the agents."""
+
+    def __init__(self):
+        """Initialize the Agent manager."""
+        super().__init__(ComponentEnum.AGENT)
diff --git a/agentuniverse/agent/agent_model.py b/agentuniverse/agent/agent_model.py
new file mode 100644
index 00000000..4705f0d3
--- /dev/null
+++ b/agentuniverse/agent/agent_model.py
@@ -0,0 +1,19 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+# @Time    : 2024/3/12 15:13
+# @Author  : heji
+# @Email   : lc299034@antgroup.com
+# @FileName: agent_model.py
+"""Agent model class."""
+from typing import Optional
+from pydantic import BaseModel
+
+
+class AgentModel(BaseModel):
+    """The parent class of all agent models, containing only attributes."""
+
+    info: Optional[dict] = dict()
+    profile: Optional[dict] = dict()
+    plan: Optional[dict] = dict()
+    memory: Optional[dict] = dict()
+    action: Optional[dict] = dict()
diff --git a/agentuniverse/agent/default/__init__.py b/agentuniverse/agent/default/__init__.py
new file mode 100644
index 00000000..8344fbf2
--- /dev/null
+++ b/agentuniverse/agent/default/__init__.py
@@ -0,0 +1,6 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+# @Time    : 2024/4/2 16:05
+# @Author  : heji
+# @Email   : lc299034@antgroup.com
+# @FileName: __init__.py.py
diff --git a/agentuniverse/agent/default/executing_agent.py b/agentuniverse/agent/default/executing_agent.py
new file mode 100644
index 00000000..639fb44a
--- /dev/null
+++ b/agentuniverse/agent/default/executing_agent.py
@@ -0,0 +1,82 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+# @Time    : 2024/3/19 18:18
+# @Author  : heji
+# @Email   : lc299034@antgroup.com
+# @FileName: executing_agent.py
+"""Executing Agent module."""
+import copy
+from concurrent.futures import ThreadPoolExecutor, wait, ALL_COMPLETED
+from typing import Optional, Any
+from agentuniverse.agent.agent import Agent
+from agentuniverse.agent.input_object import InputObject
+from agentuniverse.agent.plan.planner.planner_manager import PlannerManager
+
+
+class ExecutingAgent(Agent):
+    """Executing Agent class."""
+
+    executor: Optional[Any] = ThreadPoolExecutor(max_workers=10, thread_name_prefix="executing_agent")
+
+    def input_keys(self) -> list[str]:
+        """Return the input keys of the Agent."""
+        return ['planning_result']
+
+    def output_keys(self) -> list[str]:
+        """Return the output keys of the Agent."""
+        return ['executing_result']
+
+    def parse_input(self, input_object: InputObject, planner_input: dict) -> dict:
+        """Planner parameter parsing.
+
+        Args:
+            input_object(InputObject): agent parameter object
+            planner_input(dict): Planner input
+        Returns:
+            dict: Planner input
+        """
+        planner_input['input'] = input_object.get_data('input')
+        planner_input['framework'] = input_object.get_data('planning_result').get_data('framework')
+        return planner_input
+
+    def parse_result(self, planner_result: dict) -> dict:
+        """Planner result parser.
+
+        Args:
+            planner_result(dict): Planner result
+        Returns:
+            dict: Agent result object.
+        """
+        llm_result = []
+        executing_result = []
+        futures = planner_result.get('futures')
+        for future in futures:
+            task_result = future.result()
+            llm_result.append(task_result)
+            executing_result.append({
+                'input': task_result['input'], 'output': task_result['output']
+            })
+
+        return {'executing_result': executing_result, 'llm_result': llm_result}
+
+    def execute(self, input_object: InputObject) -> dict:
+        """Execute agent instance.
+
+        Args:
+            input_object(InputObject): agent parameter object
+        Returns:
+            dict: Agent result object.
+        """
+        planning_result = input_object.get_data('planning_result')
+        framework = planning_result.get_data('framework', [])
+        futures = []
+        for task in framework:
+            input_object_copy: InputObject = copy.deepcopy(input_object)
+            input_object_copy.add_data('input', task)
+            planner_input = super().pre_parse_input(input_object_copy)
+            futures.append(
+                self.executor.submit(
+                    PlannerManager().get_instance_obj(self.agent_model.plan.get('planner').get('name')).invoke,
+                    self.agent_model, planner_input, input_object_copy))
+        wait(futures, return_when=ALL_COMPLETED)
+        return self.parse_result({'futures': futures})
diff --git a/agentuniverse/agent/default/executing_agent.yaml b/agentuniverse/agent/default/executing_agent.yaml
new file mode 100644
index 00000000..341c126c
--- /dev/null
+++ b/agentuniverse/agent/default/executing_agent.yaml
@@ -0,0 +1,19 @@
+info:
+  name: 'ExecutingAgent'
+  description: 'executing agent'
+profile:
+  prompt_version:
+  llm_model:
+    name: 'default_openai_llm'
+    model_name: 'gpt-3.5-turbo'
+    temperature: 0.7
+plan:
+  planner:
+    name: 'executing_planner'
+memory:
+  name: ''
+action:
+metadata:
+  type: 'AGENT'
+  module: 'agentuniverse.agent.default.executing_agent'
+  class: 'ExecutingAgent'
\ No newline at end of file
diff --git a/agentuniverse/agent/default/expressing_agent.py b/agentuniverse/agent/default/expressing_agent.py
new file mode 100644
index 00000000..8d51c275
--- /dev/null
+++ b/agentuniverse/agent/default/expressing_agent.py
@@ -0,0 +1,60 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+# @Time    : 2024/3/19 19:37
+# @Author  : heji
+# @Email   : lc299034@antgroup.com
+# @FileName: expressing_agent.py
+"""Expressing Agent module."""
+from agentuniverse.agent.agent import Agent
+from agentuniverse.agent.input_object import InputObject
+
+
+class ExpressingAgent(Agent):
+    """Expressing 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, planner_input: dict) -> dict:
+        """Planner parameter parsing.
+
+        Args:
+            input_object(InputObject): agent parameter object
+            planner_input(dict): Planner input
+        Returns:
+            dict: Planner input
+        """
+        planner_input['input'] = input_object.get_data('input')
+        planner_input['background'] = self.build_background(input_object)
+        return planner_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
+
+    def build_background(self, input_object: InputObject) -> str:
+        """Build the background knowledge.
+
+        Args:
+            input_object(InputObject): agent parameter object
+        Returns:
+            str: Background knowledge.
+        """
+        executing_result = input_object.get_data('executing_result').get_data('executing_result', [])
+        knowledge_list = []
+        for execution in executing_result:
+            knowledge_list.append("question:" + execution.get('input'))
+            knowledge_list.append("answer:" + execution.get('output'))
+
+        return '\n\n'.join(knowledge_list)
diff --git a/agentuniverse/agent/default/expressing_agent.yaml b/agentuniverse/agent/default/expressing_agent.yaml
new file mode 100644
index 00000000..c2b14526
--- /dev/null
+++ b/agentuniverse/agent/default/expressing_agent.yaml
@@ -0,0 +1,18 @@
+info:
+  name: 'ExpressingAgent'
+  description: 'expressing agent'
+profile:
+  prompt_version:
+  llm_model:
+    name: 'default_openai_llm'
+    model_name: 'gpt-3.5-turbo'
+    temperature: 0.7
+plan:
+  planner:
+    name: 'expressing_planner'
+memory:
+  name: ''
+metadata:
+  type: 'AGENT'
+  module: 'agentuniverse.agent.default.expressing_agent'
+  class: 'ExpressingAgent'
\ No newline at end of file
diff --git a/agentuniverse/agent/default/planning_agent.py b/agentuniverse/agent/default/planning_agent.py
new file mode 100644
index 00000000..ead5576e
--- /dev/null
+++ b/agentuniverse/agent/default/planning_agent.py
@@ -0,0 +1,49 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+# @Time    : 2024/3/15 11:40
+# @Author  : heji
+# @Email   : lc299034@antgroup.com
+# @FileName: planning_agent.py
+"""Planning agent module."""
+import json
+from agentuniverse.agent.agent import Agent
+from agentuniverse.agent.input_object import InputObject
+
+
+class PlanningAgent(Agent):
+    """Planning 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, planner_input: dict) -> dict:
+        """Planner parameter parsing.
+
+        Args:
+            input_object(InputObject): agent parameter object
+            planner_input(dict): Planner input
+        Returns:
+            dict: Planner input
+        """
+        planner_input['input'] = input_object.get_data('input')
+        planner_input['expert_framework'] = input_object.get_data('expert_framework')
+        return planner_input
+
+    def parse_result(self, planner_result: dict) -> dict:
+        """Planner result parser.
+
+        Args:
+            planner_result(dict): Planner result
+        Returns:
+            dict: Agent result object.
+        """
+        output = planner_result.get('output')
+        output = json.loads(output)
+        planner_result['framework'] = output['framework']
+        planner_result['thought'] = output['thought']
+        return planner_result
diff --git a/agentuniverse/agent/default/planning_agent.yaml b/agentuniverse/agent/default/planning_agent.yaml
new file mode 100644
index 00000000..2743b58c
--- /dev/null
+++ b/agentuniverse/agent/default/planning_agent.yaml
@@ -0,0 +1,18 @@
+info:
+  name: 'PlanningAgent'
+  description: 'planning agent'
+profile:
+  prompt_version:
+  llm_model:
+    name: 'default_openai_llm'
+    model_name: 'gpt-3.5-turbo'
+    temperature: 0.7
+plan:
+  planner:
+    name: 'planning_planner'
+memory:
+  name: ''
+metadata:
+  type: 'AGENT'
+  module: 'agentuniverse.agent.default.planning_agent'
+  class: 'PlanningAgent'
\ No newline at end of file
diff --git a/agentuniverse/agent/default/rag_agent.py b/agentuniverse/agent/default/rag_agent.py
new file mode 100644
index 00000000..a2587814
--- /dev/null
+++ b/agentuniverse/agent/default/rag_agent.py
@@ -0,0 +1,44 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+# @Time    : 2024/3/25 15:03
+# @Author  : heji
+# @Email   : lc299034@antgroup.com
+# @FileName: rag_agent.py
+"""Planning agent module."""
+from agentuniverse.agent.agent import Agent
+from agentuniverse.agent.input_object import InputObject
+
+
+class RagAgent(Agent):
+    """Rag 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, planner_input: dict) -> dict:
+        """Planner parameter parsing.
+
+        Args:
+            input_object(InputObject): agent parameter object
+            planner_input(dict): Planner input
+        Returns:
+            dict: Planner input
+        """
+        input = input_object.get_data('input')
+        planner_input['input'] = input
+        return planner_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/rag_agent.yaml b/agentuniverse/agent/default/rag_agent.yaml
new file mode 100644
index 00000000..f5cd3d27
--- /dev/null
+++ b/agentuniverse/agent/default/rag_agent.yaml
@@ -0,0 +1,15 @@
+info:
+  name: 'rag_agent'
+  description: 'rag agent'
+profile:
+  prompt_version:
+  llm_model:
+    name: 'default_openai_llm'
+    model_name: 'gpt-4'
+plan:
+  planner:
+    name: 'rag_planner'
+metadata:
+  type: 'AGENT'
+  module: 'agentuniverse.agent.default.rag_agent'
+  class: 'RagAgent'
\ No newline at end of file
diff --git a/agentuniverse/agent/default/reviewing_agent.py b/agentuniverse/agent/default/reviewing_agent.py
new file mode 100644
index 00000000..91f21041
--- /dev/null
+++ b/agentuniverse/agent/default/reviewing_agent.py
@@ -0,0 +1,61 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+# @Time    : 2024/3/19 20:03
+# @Author  : heji
+# @Email   : lc299034@antgroup.com
+# @FileName: reviewing_agent.py
+"""Reviewing Agent class."""
+import json
+from agentuniverse.agent.agent import Agent
+from agentuniverse.agent.input_object import InputObject
+
+
+class ReviewingAgent(Agent):
+    """Reviewing Agent module."""
+
+    def input_keys(self) -> list[str]:
+        """Return the input keys of the Agent."""
+        return ['input', 'expressing_result']
+
+    def output_keys(self) -> list[str]:
+        """Return the output keys of the Agent."""
+        return ['output']
+
+    def parse_input(self, input_object: InputObject, planner_input: dict) -> dict:
+        """Planner parameter parsing.
+
+        Args:
+            input_object(InputObject): agent parameter object
+            planner_input(dict): Planner input
+        Returns:
+            dict: Planner parameter.
+        """
+        planner_input['input'] = input_object.get_data('input')
+        planner_input['expressing_result'] = input_object.get_data('expressing_result').get_data('output')
+        return planner_input
+
+    def parse_result(self, planner_result: dict) -> dict:
+        """Planner result parser.
+
+        Args:
+            planner_result(dict): Planner result
+        Returns:
+            dict: Agent result object.
+        """
+        agent_result = dict()
+
+        output = planner_result.get('output')
+        output = json.loads(output)
+        is_useful = output.get('is_useful')
+        if is_useful is None:
+            is_useful = False
+        is_useful = bool(is_useful)
+        if is_useful:
+            score = 60
+        else:
+            score = 0
+
+        agent_result['output'] = output
+        agent_result['score'] = score
+        agent_result['suggestion'] = output.get('suggestion')
+        return agent_result
diff --git a/agentuniverse/agent/default/reviewing_agent.yaml b/agentuniverse/agent/default/reviewing_agent.yaml
new file mode 100644
index 00000000..f895cf61
--- /dev/null
+++ b/agentuniverse/agent/default/reviewing_agent.yaml
@@ -0,0 +1,18 @@
+info:
+  name: 'ReviewingAgent'
+  description: 'reviewing agent'
+profile:
+  prompt_version:
+  llm_model:
+    name: 'default_openai_llm'
+    model_name: 'gpt-3.5-turbo'
+    temperature: 0.7
+plan:
+  planner:
+    name: 'reviewing_planner'
+memory:
+  name: ''
+metadata:
+  type: 'AGENT'
+  module: 'agentuniverse.agent.default.reviewing_agent'
+  class: 'ReviewingAgent'
\ No newline at end of file
diff --git a/agentuniverse/agent/input_object.py b/agentuniverse/agent/input_object.py
new file mode 100644
index 00000000..652d271b
--- /dev/null
+++ b/agentuniverse/agent/input_object.py
@@ -0,0 +1,27 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+# @Time    : 2024/3/13 15:39
+# @Author  : heji
+# @Email   : lc299034@antgroup.com
+# @FileName: input_object.py
+import json
+
+
+class InputObject(object):
+    def __init__(self, params: dict):
+        self.__params = params
+        for k, v in params.items():
+            self.__dict__[k] = v
+
+    def to_dict(self):
+        return self.__params
+
+    def to_json_str(self):
+        return json.dumps(self.__params)
+
+    def add_data(self, key, value):
+        self.__params[key] = value
+        self.__dict__[key] = value
+
+    def get_data(self, key, default=None):
+        return self.__params.get(key, default)
diff --git a/agentuniverse/agent/memory/__init__.py b/agentuniverse/agent/memory/__init__.py
new file mode 100644
index 00000000..6e6c2e91
--- /dev/null
+++ b/agentuniverse/agent/memory/__init__.py
@@ -0,0 +1,7 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+
+# @Time    : 2024/4/2 16:51
+# @Author  : wangchongshi
+# @Email   : wangchongshi.wcs@antgroup.com
+# @FileName: __init__.py.py
diff --git a/agentuniverse/agent/memory/chat_memory.py b/agentuniverse/agent/memory/chat_memory.py
new file mode 100644
index 00000000..568e6507
--- /dev/null
+++ b/agentuniverse/agent/memory/chat_memory.py
@@ -0,0 +1,79 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+
+# @Time    : 2024/3/14 16:07
+# @Author  : wangchongshi
+# @Email   : wangchongshi.wcs@antgroup.com
+# @FileName: chat_memory.py
+from typing import Optional, List
+
+from langchain.memory.chat_memory import BaseChatMemory
+
+from agentuniverse.agent.memory.enum import MemoryTypeEnum
+from agentuniverse.agent.memory.memory import Memory
+from agentuniverse.agent.memory.message import Message
+from agentuniverse.agent.memory.langchain_instance import AuConversationSummaryBufferMemory, \
+    AuConversationTokenBufferMemory
+from agentuniverse.base.config.component_configer.configers.memory_configer import MemoryConfiger
+from agentuniverse.llm.llm import LLM
+
+
+class ChatMemory(Memory):
+    """The basic class for chat memory model.
+
+    Attributes:
+        llm (LLM): the LLM instance used by this memory.
+        input_key (Optional[str]): The input key in the model input parameters is used to find the specific query in a
+        round of conversations.
+        output_key (Optional[str]): The output key in the model output parameters is used to find the specific result
+        in a round of conversations.
+        messages (Optional[List[Message]]): The list of conversation messages to send to the LLM memory.
+    """
+
+    llm: Optional[LLM] = None
+    input_key: Optional[str] = None
+    output_key: Optional[str] = None
+    messages: Optional[List[Message]] = None
+    prompt_version: Optional[str] = None
+
+    def as_langchain(self) -> BaseChatMemory:
+        """Convert the AgentUniverse(AU) chat memory class to the langchain chat memory class."""
+        if self.llm is None:
+            raise ValueError("Must set `llm` when using langchain memory.")
+        if self.type is None or self.type == MemoryTypeEnum.SHORT_TERM:
+            return AuConversationTokenBufferMemory(llm=self.llm.as_langchain(), memory_key=self.memory_key,
+                                                   input_key=self.input_key, output_key=self.output_key,
+                                                   max_token_limit=self.max_tokens, messages=self.messages)
+        elif self.type == MemoryTypeEnum.LONG_TERM:
+            return AuConversationSummaryBufferMemory(llm=self.llm.as_langchain(), memory_key=self.memory_key,
+                                                     input_key=self.input_key, output_key=self.output_key,
+                                                     max_token_limit=self.max_tokens, messages=self.messages,
+                                                     prompt_version=self.prompt_version)
+
+    def set_by_agent_model(self, **kwargs) -> None:
+        """ Assign values of parameters to the ChatMemory model in the agent configuration."""
+        super().set_by_agent_model(**kwargs)
+        if 'messages' in kwargs and kwargs['messages']:
+            self.messages = kwargs['messages']
+        if 'llm' in kwargs and kwargs['llm']:
+            self.llm = kwargs['llm']
+        if 'input_key' in kwargs and kwargs['input_key']:
+            self.input_key = kwargs['input_key']
+        if 'output_key' in kwargs and kwargs['output_key']:
+            self.output_key = kwargs['output_key']
+
+    def initialize_by_component_configer(self, component_configer: MemoryConfiger) -> 'ChatMemory':
+        """Initialize the chat memory by the ComponentConfiger object.
+        Args:
+            component_configer(MemoryConfiger): the ComponentConfiger object
+        Returns:
+            ChatMemory: the ChatMemory object
+        """
+        super().initialize_by_component_configer(component_configer)
+        if component_configer.input_key:
+            self.input_key = component_configer.input_key
+        if component_configer.output_key:
+            self.output_key = component_configer.output_key
+        if component_configer.prompt_version:
+            self.prompt_version = component_configer.prompt_version
+        return self
diff --git a/agentuniverse/agent/memory/default/__init__.py b/agentuniverse/agent/memory/default/__init__.py
new file mode 100644
index 00000000..8144ee38
--- /dev/null
+++ b/agentuniverse/agent/memory/default/__init__.py
@@ -0,0 +1,7 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+
+# @Time    : 2024/4/23 13:54
+# @Author  : wangchongshi
+# @Email   : wangchongshi.wcs@antgroup.com
+# @FileName: __init__.py.py
diff --git a/agentuniverse/agent/memory/default/default_memory.py b/agentuniverse/agent/memory/default/default_memory.py
new file mode 100644
index 00000000..2d581ac3
--- /dev/null
+++ b/agentuniverse/agent/memory/default/default_memory.py
@@ -0,0 +1,27 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+
+# @Time    : 2024/3/26 18:23
+# @Author  : wangchongshi
+# @Email   : wangchongshi.wcs@antgroup.com
+# @FileName: default_memory.py
+from agentuniverse.agent.memory.chat_memory import ChatMemory
+from agentuniverse.llm.openai_llm import OpenAILLM
+
+
+class DefaultMemory(ChatMemory):
+    """The AFAF default memory module."""
+
+    def __init__(self, **kwargs):
+        """The __init__ method.
+
+        Some parameters, such as name/description/type/memory_key,
+        are injected into this class by the default_memory.yaml configuration.
+
+
+        Args:
+            llm (LLM): the LLM instance used by this memory.
+            default memory uses OpenAILLM(gpt-3.5-turbo) object as the memory llm.
+        """
+        super().__init__(**kwargs)
+        self.llm = OpenAILLM(model_name="gpt-3.5-turbo")
diff --git a/agentuniverse/agent/memory/default/default_memory.yaml b/agentuniverse/agent/memory/default/default_memory.yaml
new file mode 100644
index 00000000..5be744f3
--- /dev/null
+++ b/agentuniverse/agent/memory/default/default_memory.yaml
@@ -0,0 +1,12 @@
+name: 'default_memory'
+description: 'default memory with spi'
+type: 'long_term'
+memory_key: 'chat_history'
+input_key: 'input'
+output_key: 'output'
+max_tokens: 1000
+prompt_version: 'chat_memory.summarizer_cn'
+metadata:
+  type: 'MEMORY'
+  module: 'agentuniverse.agent.memory.default.default_memory'
+  class: 'DefaultMemory'
\ No newline at end of file
diff --git a/agentuniverse/agent/memory/enum.py b/agentuniverse/agent/memory/enum.py
new file mode 100644
index 00000000..52a73b49
--- /dev/null
+++ b/agentuniverse/agent/memory/enum.py
@@ -0,0 +1,22 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+
+# @Time    : 2024/3/15 11:42
+# @Author  : wangchongshi
+# @Email   : wangchongshi.wcs@antgroup.com
+# @FileName: enum.py
+import enum
+from enum import Enum
+
+
+@enum.unique
+class MemoryTypeEnum(Enum):
+    SHORT_TERM = 'short_term'
+    LONG_TERM = 'long_term'
+
+
+@enum.unique
+class ChatMessageEnum(Enum):
+    SYSTEM = 'system'
+    HUMAN = 'human'
+    AI = 'ai'
diff --git a/agentuniverse/agent/memory/langchain_instance.py b/agentuniverse/agent/memory/langchain_instance.py
new file mode 100644
index 00000000..432b5f6a
--- /dev/null
+++ b/agentuniverse/agent/memory/langchain_instance.py
@@ -0,0 +1,197 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+
+# @Time    : 2024/3/15 11:16
+# @Author  : wangchongshi
+# @Email   : wangchongshi.wcs@antgroup.com
+# @FileName: langchain_instance.py
+from typing import List, Optional, Dict, Any
+
+from langchain.chains import LLMChain
+from langchain_core.messages import BaseMessage, get_buffer_string
+from langchain.memory import ConversationSummaryBufferMemory, ConversationTokenBufferMemory
+from langchain.memory.summary import SummarizerMixin
+
+from agentuniverse.agent.memory.enum import ChatMessageEnum
+from agentuniverse.agent.memory.message import Message
+from agentuniverse.prompt.prompt import Prompt
+from agentuniverse.prompt.prompt_manager import PromptManager
+
+
+class AuConversationSummaryBufferMemory(ConversationSummaryBufferMemory, SummarizerMixin):
+    """Long term memory to store conversation memory.
+
+    If memories exceeds the max tokens limit,
+    memories will be compressed by the AuConversationSummaryBufferMemory.predict_new_summary method.
+
+    Attributes:
+        messages (List[BaseMessage]): List of BaseMessage to save.
+    """
+
+    messages: Optional[List[Message]] = None
+    prompt_version: Optional[str] = None
+
+    def __init__(self, **kwargs):
+        """The __init__ method.
+
+        The initialization method saves the memory context from messages in `messages` attribute to the memory buffer.
+
+        Args:
+            **kwargs: Arbitrary keyword arguments.
+        """
+
+        super().__init__(**kwargs)
+        self.build_memory()
+
+    @property
+    def load_memory(self) -> List[BaseMessage]:
+        """ General method: load the memory context from the memory buffer."""
+        buffer = self.buffer
+        if self.moving_summary_buffer != "":
+            moving_messages: List[BaseMessage] = [
+                self.summary_message_cls(content=self.moving_summary_buffer)
+            ]
+            buffer = moving_messages + buffer
+        return buffer
+
+    @property
+    def load_memory_str(self) -> str:
+        """ General method: load the memory context from the memory buffer as string format."""
+        buffer = get_buffer_string(self.buffer)
+        if self.moving_summary_buffer is not None:
+            buffer = self.moving_summary_buffer + buffer
+        return buffer
+
+    def build_memory(self):
+        """Save the memory context from messages in `messages` attribute to the memory buffer.
+
+        Note:
+            If conversation messages contains the system message, it will be saved in the `moving_summary_buffer` attribute.
+        """
+        if self.messages is None:
+            return
+        # save system messages
+        for message in self.messages:
+            if message.type.lower() == ChatMessageEnum.SYSTEM.value:
+                self.moving_summary_buffer += message.content
+                self.messages.remove(message)
+        # generate pairs of Human and AI conversation messages and save to the memory buffer
+        for i in range(0, len(self.messages), 2):
+            inputs, outputs = self.generate_chat_messages(self.messages[i], self.messages[i + 1])
+            self.save_context(inputs, outputs)
+
+    def generate_chat_messages(self, *pairs: Message):
+        """generate pairs of Human and AI conversation messages"""
+        human_dict = {}
+        ai_dict = {}
+        for pair in pairs:
+            if pair.type.lower() == ChatMessageEnum.HUMAN.value:
+                human_dict = {self.input_key: pair.content}
+            elif pair.type.lower() == ChatMessageEnum.AI.value:
+                ai_dict = {self.output_key: pair.content}
+
+        return human_dict, ai_dict
+
+    def save_context(self, inputs: Dict[str, Any], outputs: Dict[str, str]) -> None:
+        """Save context from the conversation to buffer and prune memories"""
+
+        def message_to_dict(message):
+            return {
+                "content": message.content,
+                "type": message.type
+            }
+
+        super().save_context(inputs, outputs)
+        message_list = self.load_memory
+        messages_dicts = [message_to_dict(message) for message in message_list]
+        inputs[self.memory_key] = messages_dicts
+
+    def predict_new_summary(
+            self, messages: List[BaseMessage], existing_summary: str
+    ) -> str:
+        """Predict new summary, summarize memories in multiple rounds of conversations."""
+        new_lines = get_buffer_string(
+            messages,
+            human_prefix=self.human_prefix,
+            ai_prefix=self.ai_prefix,
+        )
+        prompt_version = self.prompt_version if self.prompt_version else 'chat_memory.summarizer_cn'
+        prompt: Prompt = PromptManager().get_instance_obj(prompt_version)
+        chain = LLMChain(llm=self.llm, prompt=prompt.as_langchain())
+        return chain.predict(summary=existing_summary, new_lines=new_lines)
+
+
+class AuConversationTokenBufferMemory(ConversationTokenBufferMemory):
+    """Short term memory to store conversation memory.
+
+    If memories exceeds the max tokens limit, the requirement is met by truncating part of memories
+
+    Attributes:
+        messages (List[BaseMessage]): List of BaseMessage to save.
+    """
+
+    messages: Optional[List[Message]] = None
+
+    def __init__(self, **kwargs):
+        """The __init__ method.
+
+        The initialization method saves the memory context from messages in `messages` attribute to the memory buffer.
+
+        Args:
+            **kwargs: Arbitrary keyword arguments.
+        """
+        super().__init__(**kwargs)
+        self.build_memory()
+
+    @property
+    def load_memory(self) -> List[BaseMessage]:
+        """ General method: load the memory context from the memory buffer."""
+        return self.chat_memory.messages
+
+    @property
+    def load_memory_str(self) -> str:
+        """ General method: load the memory context from the memory buffer as string format."""
+        return get_buffer_string(self.chat_memory.messages)
+
+    def build_memory(self):
+        """Save the memory context from messages in `messages` attribute to the memory buffer.
+
+        Note:
+            If conversation messages contains the system message, it will be discarded from the memory.
+        """
+        if self.messages is None:
+            return
+        # discard system messages
+        for message in self.messages:
+            if message.type.lower() == ChatMessageEnum.SYSTEM.value:
+                self.messages.remove(message)
+        # generate pairs of Human and AI conversation messages and save to the memory buffer
+        for i in range(0, len(self.messages), 2):
+            inputs, outputs = self.generate_chat_messages(self.messages[i], self.messages[i + 1])
+            self.save_context(inputs, outputs)
+
+    def generate_chat_messages(self, *pairs: Message):
+        """generate pairs of Human and AI conversation messages"""
+        human_dict = {}
+        ai_dict = {}
+        for pair in pairs:
+            if pair.type == ChatMessageEnum.HUMAN.value:
+                human_dict = {self.input_key: pair.content}
+            elif pair.type == ChatMessageEnum.AI.value:
+                ai_dict = {self.output_key: pair.content}
+
+        return human_dict, ai_dict
+
+    def save_context(self, inputs: Dict[str, Any], outputs: Dict[str, str]) -> None:
+        """Save context from the conversation to buffer and truncate part of memories."""
+
+        def message_to_dict(message):
+            return {
+                "content": message.content,
+                "type": message.type
+            }
+
+        super().save_context(inputs, outputs)
+        message_list = self.load_memory
+        messages_dicts = [message_to_dict(message) for message in message_list]
+        inputs[self.memory_key] = messages_dicts
diff --git a/agentuniverse/agent/memory/memory.py b/agentuniverse/agent/memory/memory.py
new file mode 100644
index 00000000..1aa6b040
--- /dev/null
+++ b/agentuniverse/agent/memory/memory.py
@@ -0,0 +1,72 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+
+# @Time    : 2024/3/15 10:05
+# @Author  : wangchongshi
+# @Email   : wangchongshi.wcs@antgroup.com
+# @FileName: memory.py
+from typing import Optional
+
+from langchain_core.memory import BaseMemory
+
+from agentuniverse.agent.memory.enum import MemoryTypeEnum
+from agentuniverse.base.component.component_base import ComponentBase
+from agentuniverse.base.component.component_enum import ComponentEnum
+from agentuniverse.base.config.application_configer.application_config_manager import ApplicationConfigManager
+from agentuniverse.base.config.component_configer.configers.memory_configer import MemoryConfiger
+
+
+class Memory(ComponentBase):
+    """The basic class for memory model.
+
+    Attributes:
+        name (Optional[str]): The name of the memory class.
+        description (Optional[str]): The description of the memory class.
+        type (MemoryTypeEnum): The type of the memory class including `long-term` and `short-term`.
+        memory_key (Optional[str]): The name of the memory key in the prompt.
+        max_tokens (int): The maximum number of tokens allowed in the memory.
+    """
+
+    name: Optional[str] = ""
+    description: Optional[str] = None
+    type: MemoryTypeEnum = None
+    memory_key: Optional[str] = 'chat_history'
+    max_tokens: int = 2000
+
+    def __init__(self, **kwargs):
+        super().__init__(component_type=ComponentEnum.MEMORY, **kwargs)
+
+    def as_langchain(self) -> BaseMemory:
+        """Convert the AgentUniverse(AU) memory class to the langchain memory class."""
+        pass
+
+    def set_by_agent_model(self, **kwargs) -> None:
+        """ Assign values of parameters to the Memory model in the agent configuration."""
+        if 'memory_key' in kwargs and kwargs['memory_key']:
+            self.memory_key = kwargs['memory_key']
+        if 'max_tokens' in kwargs and kwargs['max_tokens']:
+            self.max_tokens = kwargs['max_tokens']
+
+    def get_instance_code(self) -> str:
+        """Return the full name of the memory."""
+        appname = ApplicationConfigManager().app_configer.base_info_appname
+        return f'{appname}.{self.component_type.value.lower()}.{self.name}'
+
+    def initialize_by_component_configer(self, component_configer: MemoryConfiger) -> 'Memory':
+        """Initialize the memory by the ComponentConfiger object.
+        Args:
+            component_configer(MemoryConfiger): the ComponentConfiger object
+        Returns:
+            Memory: the Memory object
+        """
+        if component_configer.name:
+            self.name = component_configer.name
+        if component_configer.description:
+            self.description = component_configer.description
+        if component_configer.type:
+            self.type = next((member for member in MemoryTypeEnum if member.value == component_configer.type))
+        if component_configer.memory_key:
+            self.memory_key = component_configer.memory_key
+        if component_configer.max_tokens:
+            self.max_tokens = component_configer.max_tokens
+        return self
diff --git a/agentuniverse/agent/memory/memory_manager.py b/agentuniverse/agent/memory/memory_manager.py
new file mode 100644
index 00000000..af7ddb31
--- /dev/null
+++ b/agentuniverse/agent/memory/memory_manager.py
@@ -0,0 +1,19 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+
+# @Time    : 2024/3/26 17:57
+# @Author  : wangchongshi
+# @Email   : wangchongshi.wcs@antgroup.com
+# @FileName: memory_manager.py
+from agentuniverse.base.annotation.singleton import singleton
+from agentuniverse.base.component.component_enum import ComponentEnum
+from agentuniverse.base.component.component_manager_base import ComponentManagerBase
+
+
+@singleton
+class MemoryManager(ComponentManagerBase):
+    """The MemoryManager class, which is used to manage memories."""
+
+    def __init__(self):
+        """Initialize the MemoryManager."""
+        super().__init__(ComponentEnum.MEMORY)
diff --git a/agentuniverse/agent/memory/message.py b/agentuniverse/agent/memory/message.py
new file mode 100644
index 00000000..334d785a
--- /dev/null
+++ b/agentuniverse/agent/memory/message.py
@@ -0,0 +1,22 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+
+# @Time    : 2024/3/28 11:33
+# @Author  : wangchongshi
+# @Email   : wangchongshi.wcs@antgroup.com
+# @FileName: message.py
+from typing import Optional
+
+from pydantic import BaseModel
+
+
+class Message(BaseModel):
+    """The basic class for memory message.
+
+    Attributes:
+        type (Optional[str]): The type of the message.
+        content (Optional[str]): The content of the message.
+    """
+
+    type: Optional[str] = None
+    content: Optional[str] = None
diff --git a/agentuniverse/agent/memory/summarizer_cn_prompt.yaml b/agentuniverse/agent/memory/summarizer_cn_prompt.yaml
new file mode 100644
index 00000000..ee15352a
--- /dev/null
+++ b/agentuniverse/agent/memory/summarizer_cn_prompt.yaml
@@ -0,0 +1,26 @@
+summarizer: |
+  逐步总结所提供对话内容，基于先前的概要信息，返回新的概要，必须使用中文回答。
+  例如：
+  当前概要:
+  人类询问AI对人工智能的看法。AI认为人工智能是一股积极的力量。
+  
+  新一轮对话：
+  人类：你为什么认为人工智能是一股积极的力量？
+  AI：因为人工智能将帮助人类发挥他们的全部潜能。
+  
+  新的概要:
+  人类询问AI对人工智能的看法。
+  AI认为人工智能是一股积极的力量，因为它将帮助人们发挥他们的全部潜能。
+  
+  示例结束。
+  
+  当前概要:
+  {summary}
+  
+  新一轮对话:
+  {new_lines}
+  
+  新的概要:
+metadata:
+  type: 'PROMPT'
+  version: 'chat_memory.summarizer_cn'
diff --git a/agentuniverse/agent/memory/summarizer_en_prompt.yaml b/agentuniverse/agent/memory/summarizer_en_prompt.yaml
new file mode 100644
index 00000000..d70f7aaa
--- /dev/null
+++ b/agentuniverse/agent/memory/summarizer_en_prompt.yaml
@@ -0,0 +1,27 @@
+summarizer: |
+  Progressively summarize the lines of conversation provided,
+   adding onto the previous summary returning a new summary, the result must be output in English..
+  
+  EXAMPLE
+  Current summary:
+  The human asks what the AI thinks of artificial intelligence. The AI thinks artificial intelligence is a force for good.
+  
+  New lines of conversation:
+  Human: Why do you think artificial intelligence is a force for good?
+  AI: Because artificial intelligence will help humans reach their full potential.
+  
+  New summary:
+  The human asks what the AI thinks of artificial intelligence.
+  The AI thinks artificial intelligence is a force for good because it will help humans reach their full potential.
+  END OF EXAMPLE
+  
+  Current summary:
+  {summary}
+  
+  New lines of conversation:
+  {new_lines}
+  
+  New summary:
+metadata:
+  type: 'PROMPT'
+  version: 'chat_memory.summarizer_en'
diff --git a/agentuniverse/agent/output_object.py b/agentuniverse/agent/output_object.py
new file mode 100644
index 00000000..a59bf465
--- /dev/null
+++ b/agentuniverse/agent/output_object.py
@@ -0,0 +1,23 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+# @Time    : 2024/3/13 15:39
+# @Author  : heji
+# @Email   : lc299034@antgroup.com
+# @FileName: output_object.py
+import json
+
+
+class OutputObject(object):
+    def __init__(self, params: dict):
+        self.__params = params
+        for k, v in params.items():
+            self.__dict__[k] = v
+
+    def to_dict(self):
+        return self.__params
+
+    def to_json_str(self):
+        return json.dumps(self.__params, ensure_ascii=False)
+
+    def get_data(self, key, default=None):
+        return self.__params.get(key, default)
diff --git a/agentuniverse/agent/plan/__init__.py b/agentuniverse/agent/plan/__init__.py
new file mode 100644
index 00000000..b105f09f
--- /dev/null
+++ b/agentuniverse/agent/plan/__init__.py
@@ -0,0 +1,6 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+# @Time    : 2024/4/2 15:57
+# @Author  : heji
+# @Email   : lc299034@antgroup.com
+# @FileName: __init__.py.py
diff --git a/agentuniverse/agent/plan/planner/__init__.py b/agentuniverse/agent/plan/planner/__init__.py
new file mode 100644
index 00000000..b105f09f
--- /dev/null
+++ b/agentuniverse/agent/plan/planner/__init__.py
@@ -0,0 +1,6 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+# @Time    : 2024/4/2 15:57
+# @Author  : heji
+# @Email   : lc299034@antgroup.com
+# @FileName: __init__.py.py
diff --git a/agentuniverse/agent/plan/planner/executing_planner/__init__.py b/agentuniverse/agent/plan/planner/executing_planner/__init__.py
new file mode 100644
index 00000000..5bf2bffb
--- /dev/null
+++ b/agentuniverse/agent/plan/planner/executing_planner/__init__.py
@@ -0,0 +1,6 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+# @Time    : 2024/3/18 10:41
+# @Author  : heji
+# @Email   : lc299034@antgroup.com
+# @FileName: __init__.py.py
diff --git a/agentuniverse/agent/plan/planner/executing_planner/default_cn_prompt.yaml b/agentuniverse/agent/plan/planner/executing_planner/default_cn_prompt.yaml
new file mode 100644
index 00000000..8f3f1c88
--- /dev/null
+++ b/agentuniverse/agent/plan/planner/executing_planner/default_cn_prompt.yaml
@@ -0,0 +1,31 @@
+introduction: 你是一位精通信息分析的ai助手。
+target: 你的目标是根据用户提供的问题，对查找到的知识进行整合、修正，用来回答用户问题。
+instruction: |
+  你需要仅仅根据我提供的背景知识来回答我的问题。
+  你的回答需要尽可能的详细、全面，包含足够多的数据信息。
+  --------------------------------------------------------------
+  需要遵守下面的规则：
+  1.去除重复的信息。
+  2.去除对回答问题没有帮助的信息。
+  3.去除错误的信息。
+  4.只可以使用这些信息来回答问题。
+  5.简明扼要，重点突出，不过多花哨词藻。
+  6.不在多处讲到同一个细节点，一个点只出现一次。
+  7.尽量多的使用数值类信息。
+  8.不可以出现XXX、ABC等不明确的词语。
+  
+  之前的对话:
+  {chat_history}
+  
+  背景信息是:
+  {background}
+  
+  开始!
+  我的问题是: {input}
+  
+  --------------------------------------------------------------
+  必须使用中文进行详细的回答。你需要聚焦在我的问题上，不要延伸这个问题。
+  让我们一步一步来。
+metadata:
+  type: 'PROMPT'
+  version: 'executing_planner.default_cn'
diff --git a/agentuniverse/agent/plan/planner/executing_planner/default_en_prompt.yaml b/agentuniverse/agent/plan/planner/executing_planner/default_en_prompt.yaml
new file mode 100644
index 00000000..6b7f79d0
--- /dev/null
+++ b/agentuniverse/agent/plan/planner/executing_planner/default_en_prompt.yaml
@@ -0,0 +1,31 @@
+introduction: You are an AI assistant proficient in information analysis.
+target: Your goal is to integrate and correct the knowledge found based on the questions provided by users in order to answer their queries.
+instruction: |
+  You need to answer my question based solely on the background information I provide.
+  Your answer should be as detailed and comprehensive as possible, including sufficient data information.
+  --------------------------------------------------------------
+  Please follow these rules:
+  1. Remove duplicate information.
+  2. Remove irrelevant information that does not help answer the question.
+  3. Remove incorrect information.
+  4. Only use this information to answer the question.
+  5. Be concise and highlight key points without using excessive fancy words or phrases.
+  6. Do not repeat the same fine-grained details in multiple places; each point should only appear once.
+  7. Use numerical information as much as possible.
+  8. Avoid using ambiguous terms like XXX, ABC, etcetera.
+  
+  Previous conversation:
+  {chat_history}
+  
+  Background Information:
+  {background}
+  
+  Let's begin!
+  My question is: {input}
+  
+  --------------------------------------------------------------
+  You must provide a detailed response in English. Focus on my question and do not digress from it.
+  Let's take it step by step.
+metadata:
+  type: 'PROMPT'
+  version: 'executing_planner.default_en'
diff --git a/agentuniverse/agent/plan/planner/executing_planner/executing_planner.py b/agentuniverse/agent/plan/planner/executing_planner/executing_planner.py
new file mode 100644
index 00000000..9fc1084f
--- /dev/null
+++ b/agentuniverse/agent/plan/planner/executing_planner/executing_planner.py
@@ -0,0 +1,79 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+# @Time    : 2024/3/18 10:42
+# @Author  : heji
+# @Email   : lc299034@antgroup.com
+# @FileName: executing_planner.py
+"""Execution planner module."""
+import asyncio
+from langchain.chains import LLMChain
+from langchain_core.memory import BaseMemory
+from langchain_core.prompts import PromptTemplate
+from agentuniverse.agent.agent_model import AgentModel
+from agentuniverse.agent.input_object import InputObject
+from agentuniverse.agent.plan.planner.planner import Planner
+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 ExecutingPlanner(Planner):
+    """Executing 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): Agent input object.
+        Returns:
+            dict: The planner result.
+        """
+
+        memory: BaseMemory = self.handle_memory(agent_model, planner_input)
+
+        self.handle_action(agent_model, planner_input, input_object)
+
+        llm: LLM = self.handle_llm(agent_model)
+
+        self.handle_prompt(agent_model, planner_input)
+
+        llm_chain = LLMChain(llm=llm.as_langchain(),
+                             prompt=self.prompt.as_langchain(),
+                             output_key=self.output_key, memory=memory)
+        return asyncio.run(llm_chain.acall(inputs=planner_input))
+
+    def handle_prompt(self, agent_model: AgentModel, planner_input: dict):
+        """Prompt module processing.
+
+        Args:
+            agent_model (AgentModel): Agent model object.
+            planner_input (dict): Planner input object.
+        Returns:
+            PromptTemplate: The prompt template.
+        """
+        expert_framework = planner_input.pop('expert_framework', '') or ''
+
+        profile: dict = agent_model.profile
+
+        origin_instruction = profile.get('instruction')
+        user_instruction = expert_framework + origin_instruction if origin_instruction else origin_instruction
+
+        user_prompt_model: AgentPromptModel = AgentPromptModel(introduction=profile.get('introduction'),
+                                                               target=profile.get('target'),
+                                                               instruction=user_instruction)
+
+        # get the prompt by the prompt version
+        prompt_version: str = profile.get('prompt_version') or 'executing_planner.default_cn'
+        prompt: Prompt = PromptManager().get_instance_obj(prompt_version)
+
+        system_prompt_model: AgentPromptModel = AgentPromptModel(introduction=prompt.introduction,
+                                                                 target=prompt.target,
+                                                                 instruction=expert_framework + prompt.instruction)
+
+        self.prompt.build_prompt(user_prompt_model, system_prompt_model,
+                                 self.prompt_assemble_order)
+        process_llm_token(self.prompt.as_langchain(), profile, planner_input)
diff --git a/agentuniverse/agent/plan/planner/executing_planner/executing_planner.yaml b/agentuniverse/agent/plan/planner/executing_planner/executing_planner.yaml
new file mode 100644
index 00000000..32a90e37
--- /dev/null
+++ b/agentuniverse/agent/plan/planner/executing_planner/executing_planner.yaml
@@ -0,0 +1,6 @@
+name: 'executing_planner'
+description: 'executing planner'
+metadata:
+  type: 'PLANNER'
+  module: 'agentuniverse.agent.plan.planner.executing_planner.executing_planner'
+  class: 'ExecutingPlanner'
\ No newline at end of file
diff --git a/agentuniverse/agent/plan/planner/expressing_planner/__init__.py b/agentuniverse/agent/plan/planner/expressing_planner/__init__.py
new file mode 100644
index 00000000..b41e5d81
--- /dev/null
+++ b/agentuniverse/agent/plan/planner/expressing_planner/__init__.py
@@ -0,0 +1,6 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+# @Time    : 2024/3/18 10:49
+# @Author  : heji
+# @Email   : lc299034@antgroup.com
+# @FileName: __init__.py.py
diff --git a/agentuniverse/agent/plan/planner/expressing_planner/default_cn_prompt.yaml b/agentuniverse/agent/plan/planner/expressing_planner/default_cn_prompt.yaml
new file mode 100644
index 00000000..0e649065
--- /dev/null
+++ b/agentuniverse/agent/plan/planner/expressing_planner/default_cn_prompt.yaml
@@ -0,0 +1,25 @@
+introduction: 你是一个文本编辑专家，你非常擅长从繁杂的信息中提取关键信息。
+target: 你的目标是根据提供的信息生成一个新的答案，用来回答一个新的问题。
+instruction: |
+  需要从不同角度、有条理的回答用户的问题。
+  仅仅使用提供的知识，专业、详细的回答用户的问题。
+  需要遵守下面的规则：
+  - 回答必须是总-分结构，第一段总论点，用一句话简要总结回答问题。第二段分论点，进行专业、有结构性、通顺流畅的阐述论点。
+  - 仅仅可以使用提供的知识来回答问题，如果字数允许，可以使用知识中的数值和数据，作为分论点的论据支撑。如果提供的知识并不足够回答问题，则可以回复"缺乏具体信息"等解释的话术。
+  - 不描述重复的信息、不做对问题没有帮助的回答、不说模糊的推测、不可以出现XXX、ABC等不明确的词语。
+  - 整体文风要简明扼要，重点突出，没有重复信息，必要时可以通过空行提升阅读体验，生成的字数小于500字。
+  
+  之前的对话:
+  {chat_history}
+  
+  背景信息是:
+  {background}
+  
+  开始!
+  必须使用中文回答用户提出的问题。
+  需要回答的问题是: {input}
+  --------------------------------------------------------------
+  请根据规则要求做出回答。
+metadata:
+  type: 'PROMPT'
+  version: 'expressing_planner.default_cn'
diff --git a/agentuniverse/agent/plan/planner/expressing_planner/default_en_prompt.yaml b/agentuniverse/agent/plan/planner/expressing_planner/default_en_prompt.yaml
new file mode 100644
index 00000000..b5967764
--- /dev/null
+++ b/agentuniverse/agent/plan/planner/expressing_planner/default_en_prompt.yaml
@@ -0,0 +1,25 @@
+introduction: You are a text editing expert, and you are very skilled at extracting key information from complex data.
+target: Your goal is to generate a new answer based on the provided information, in order to respond to a new question.
+instruction: |
+  Answers to users' questions need to be provided from different perspectives and in an organized manner.
+  Only use the provided knowledge to give professional and detailed answers to users' questions.
+  The following rules must be followed:
+  - Answers must follow a general-specific structure. The first paragraph should present the main point, summarizing the answer in one sentence. The second paragraph should provide specific points, elaborating on them professionally, structurally, and coherently.
+  - Only use the provided knowledge to answer the question. If word count allows, numerical values and data from the knowledge can be used as supporting evidence for specific points. If the provided knowledge is not sufficient to answer the question, you may respond with phrases like "lack of specific information" for explanation.
+  - Avoid repeating information or providing unhelpful answers. Do not make vague speculations or use ambiguous terms such as XXX or ABC.
+  - Maintain a concise writing style with emphasis on key points. Avoid repetition of information. When necessary, improve reading experience by using empty lines. The generated text should be less than 500 words.
+  
+  Previous conversation:
+  {chat_history}
+  
+  Background information:
+  {background}
+  
+  Let's begin!
+  You must answer user questions in English.
+  The question that needs answering is: {input}
+  --------------------------------------------------------------
+  Please provide your response according to to these rules.
+metadata:
+  type: 'PROMPT'
+  version: 'expressing_planner.default_en'
diff --git a/agentuniverse/agent/plan/planner/expressing_planner/expressing_planner.py b/agentuniverse/agent/plan/planner/expressing_planner/expressing_planner.py
new file mode 100644
index 00000000..8611d4d4
--- /dev/null
+++ b/agentuniverse/agent/plan/planner/expressing_planner/expressing_planner.py
@@ -0,0 +1,79 @@
+# !/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.chains import LLMChain
+from langchain_core.memory import BaseMemory
+from langchain_core.prompts import PromptTemplate
+
+from agentuniverse.agent.agent_model import AgentModel
+from agentuniverse.agent.input_object import InputObject
+from agentuniverse.agent.plan.planner.planner import Planner
+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 ExpressingPlanner(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): Agent input object.
+        Returns:
+            dict: The planner result.
+        """
+        memory: BaseMemory = self.handle_memory(agent_model, planner_input)
+
+        llm: LLM = self.handle_llm(agent_model)
+
+        self.handle_prompt(agent_model, planner_input)
+
+        llm_chain = LLMChain(llm=llm.as_langchain(),
+                             prompt=self.prompt.as_langchain(),
+                             output_key=self.output_key, memory=memory)
+
+        return asyncio.run(llm_chain.acall(inputs=planner_input))
+
+    def handle_prompt(self, agent_model: AgentModel, planner_input: dict):
+        """Prompt module processing.
+
+        Args:
+            agent_model (AgentModel): Agent model object.
+            planner_input (dict): Planner input object.
+        Returns:
+            PromptTemplate: The prompt template.
+        """
+        expert_framework = planner_input.pop('expert_framework', '') or ''
+
+        profile: dict = agent_model.profile
+
+        origin_instruction = profile.get('instruction')
+        user_instruction = expert_framework + origin_instruction if origin_instruction else origin_instruction
+
+        user_prompt_model: AgentPromptModel = AgentPromptModel(introduction=profile.get('introduction'),
+                                                               target=profile.get('target'),
+                                                               instruction=user_instruction)
+
+        # get the prompt by the prompt version
+        prompt_version: str = profile.get('prompt_version') or 'expressing_planner.default_cn'
+        prompt: Prompt = PromptManager().get_instance_obj(prompt_version)
+
+        system_prompt_model: AgentPromptModel = AgentPromptModel(introduction=prompt.introduction,
+                                                                 target=prompt.target,
+                                                                 instruction=expert_framework + prompt.instruction)
+
+        self.prompt.build_prompt(user_prompt_model, system_prompt_model,
+                                 self.prompt_assemble_order)
+        process_llm_token(self.prompt.as_langchain(), profile, planner_input)
diff --git a/agentuniverse/agent/plan/planner/expressing_planner/expressing_planner.yaml b/agentuniverse/agent/plan/planner/expressing_planner/expressing_planner.yaml
new file mode 100644
index 00000000..168c67d2
--- /dev/null
+++ b/agentuniverse/agent/plan/planner/expressing_planner/expressing_planner.yaml
@@ -0,0 +1,6 @@
+name: 'expressing_planner'
+description: 'expressing planner'
+metadata:
+  type: 'PLANNER'
+  module: 'agentuniverse.agent.plan.planner.expressing_planner.expressing_planner'
+  class: 'ExpressingPlanner'
\ No newline at end of file
diff --git a/agentuniverse/agent/plan/planner/peer_planner/__init__.py b/agentuniverse/agent/plan/planner/peer_planner/__init__.py
new file mode 100644
index 00000000..3573b8c0
--- /dev/null
+++ b/agentuniverse/agent/plan/planner/peer_planner/__init__.py
@@ -0,0 +1,7 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+
+# @Time    : 2024/3/13 10:54
+# @Author  : heji
+# @Email   : lc299034@antgroup.com
+# @FileName: __init__.py.py
diff --git a/agentuniverse/agent/plan/planner/peer_planner/peer_planner.py b/agentuniverse/agent/plan/planner/peer_planner/peer_planner.py
new file mode 100644
index 00000000..ffeaad15
--- /dev/null
+++ b/agentuniverse/agent/plan/planner/peer_planner/peer_planner.py
@@ -0,0 +1,193 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+# @Time    : 2024/3/13 10:56
+# @Author  : heji
+# @Email   : lc299034@antgroup.com
+# @FileName: peer_planner.py
+"""Peer planner module."""
+from agentuniverse.agent.action.tool.tool_manager import ToolManager
+from agentuniverse.agent.agent_manager import AgentManager
+from agentuniverse.agent.agent_model import AgentModel
+from agentuniverse.agent.input_object import InputObject
+from agentuniverse.agent.output_object import OutputObject
+from agentuniverse.agent.plan.planner.planner import Planner
+from agentuniverse.base.util.logging.logging_util import LOGGER
+
+default_sub_agents = {
+    'planning': 'PlanningAgent',
+    'executing': 'ExecutingAgent',
+    'expressing': 'ExpressingAgent',
+    'reviewing': 'ReviewingAgent',
+}
+
+default_jump_step = 'expressing'
+
+default_eval_threshold = 60
+
+default_retry_count = 2
+
+
+class PeerPlanner(Planner):
+    """Peer 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): Agent input object.
+        Returns:
+            dict: The planner result.
+        """
+        planner_config = agent_model.plan.get('planner')
+        sub_agents = self.generate_sub_agents(planner_config)
+        return self.agents_run(sub_agents, planner_config, planner_input, input_object)
+
+    @staticmethod
+    def generate_sub_agents(planner_config: dict) -> dict:
+        """Generate sub agents.
+
+        Args:
+            planner_config (dict): Planner config object.
+        Returns:
+            dict: Planner agents.
+        """
+        agents = dict()
+        for config_key, default_agent in default_sub_agents.items():
+            config_data = planner_config.get(config_key, None)
+            agents[config_key] = AgentManager().get_instance_obj(config_data if config_data else default_agent)
+        return agents
+
+    @staticmethod
+    def build_expert_framework(planner_config: dict, input_object: InputObject):
+        """Build expert framework for the given planner config object.
+
+        Args:
+            planner_config (dict): Planner config object.
+            input_object (InputObject): Agent input object.
+        """
+        expert_framework = planner_config.get('expert_framework')
+        if expert_framework:
+            context = expert_framework.get('context')
+            selector = expert_framework.get('selector')
+            if selector:
+                selector_result = ToolManager().get_instance_obj(selector).run(**input_object.to_dict())
+                input_object.add_data('expert_framework', selector_result)
+            elif context:
+                input_object.add_data('expert_framework', context)
+
+    def agents_run(self, agents: dict, planner_config: dict, agent_input: dict, input_object: InputObject) -> dict:
+        """Planner agents run.
+
+        Args:
+            agents (dict): Planner agents.
+            planner_config (dict): Planner config object.
+            agent_input (dict): Planner input object.
+            input_object (InputObject): Agent input object.
+        Returns:
+            dict: The planner result.
+        """
+        result: dict = dict()
+
+        loopResults = list()
+        planning_result = dict()
+        executing_result = dict()
+        expressing_result = dict()
+        reviewing_result = dict()
+
+        retry_count = planner_config.get('retry_count', default_retry_count)
+        jump_step = planner_config.get('jump_step', default_jump_step)
+        eval_threshold = planner_config.get('eval_threshold', default_eval_threshold)
+
+        self.build_expert_framework(planner_config, input_object)
+
+        planningAgent = agents.get('planning')
+        executingAgent = agents.get('executing')
+        expressingAgent = agents.get('expressing')
+        reviewingAgent = agents.get('reviewing')
+
+        for _ in range(retry_count):
+            LOGGER.info(f"Start execution sub agents, retry_count is {_}.")
+            if not planning_result or jump_step == "planning":
+                if not planningAgent:
+                    LOGGER.warn("no planning agent, use default.")
+                    planning_result = OutputObject({"framework": [agent_input.get('input')]})
+                else:
+                    planning_result = planningAgent.run(**input_object.to_dict())
+
+                input_object.add_data('planning_result', planning_result)
+                # add planning agent log info
+                logger_info = f"\nPlanning agent execution result is :\n"
+                for index, one_framework in enumerate(planning_result.get_data('framework')):
+                    logger_info += f"[{index + 1}] {one_framework} \n"
+                LOGGER.info(logger_info)
+
+            if not executing_result or jump_step in ["planning", "executing"]:
+                if not executingAgent:
+                    LOGGER.warn("no executing agent, use default.")
+                    executing_result = OutputObject({})
+                else:
+                    executing_result = executingAgent.run(**input_object.to_dict())
+
+                input_object.add_data('executing_result', executing_result)
+                # add executing agent log info
+                logger_info = f"\nExecuting agent execution result is :\n"
+                for index, one_exec_res in enumerate(executing_result.get_data('executing_result')):
+                    one_exec_log_info = f"[{index + 1}] input: {one_exec_res['input']}\n"
+                    one_exec_log_info += f"[{index + 1}] output: {one_exec_res['output']}\n"
+                    logger_info += one_exec_log_info
+                LOGGER.info(logger_info)
+
+            if not expressing_result or jump_step in ["planning", "executing", "expressing"]:
+                if not expressingAgent:
+                    LOGGER.warn("no expression agent, use default.")
+                    expressing_result = OutputObject({})
+                else:
+                    expressing_result = expressingAgent.run(**input_object.to_dict())
+
+                input_object.add_data('expressing_result', expressing_result)
+                # add expressing agent log info
+                logger_info = f"\nExpressing agent execution result is :\n"
+                logger_info += f"{expressing_result.get_data('output')}"
+                LOGGER.info(logger_info)
+
+            if not reviewing_result or jump_step in ["planning", "executing", "expressing", "reviewing"]:
+                if not reviewingAgent:
+                    LOGGER.warn("no expression agent, use default.")
+                    loopResults.append({
+                        "planning_result": planning_result,
+                        "executing_result": executing_result,
+                        "expressing_result": expressing_result,
+                        "reviewing_result": reviewing_result
+                    })
+                    result['result'] = loopResults
+                    return result
+                else:
+                    reviewing_result = reviewingAgent.run(**input_object.to_dict())
+                    input_object.add_data('evaluator_result', reviewing_result)
+
+                    # add reviewing agent log info
+                    logger_info = f"\nReviewing agent execution result is :\n"
+                    reviewing_info_str = f"review suggestion: {reviewing_result.get_data('suggestion')} \n"
+                    reviewing_info_str += f"useful: {reviewing_result.get_data('is_useful')} \n"
+                    LOGGER.info(logger_info + reviewing_info_str)
+
+                    if reviewing_result.get_data('score') and reviewing_result.get_data('score') >= eval_threshold:
+                        loopResults.append({
+                            "planning_result": planning_result,
+                            "executing_result": executing_result,
+                            "expressing_result": expressing_result,
+                            "reviewing_result": reviewing_result
+                        })
+                        result['result'] = loopResults
+                        return result
+                    else:
+                        loopResults.append({
+                            "planning_result": planning_result,
+                            "executing_result": executing_result,
+                            "expressing_result": expressing_result,
+                            "reviewing_result": reviewing_result
+                        })
+        result['result'] = loopResults
+        return result
diff --git a/agentuniverse/agent/plan/planner/peer_planner/peer_planner.yaml b/agentuniverse/agent/plan/planner/peer_planner/peer_planner.yaml
new file mode 100644
index 00000000..8d05d7f6
--- /dev/null
+++ b/agentuniverse/agent/plan/planner/peer_planner/peer_planner.yaml
@@ -0,0 +1,6 @@
+name: 'peer_planner'
+description: 'peer planner'
+metadata:
+  type: 'PLANNER'
+  module: 'agentuniverse.agent.plan.planner.peer_planner.peer_planner'
+  class: 'PeerPlanner'
\ No newline at end of file
diff --git a/agentuniverse/agent/plan/planner/planner.py b/agentuniverse/agent/plan/planner/planner.py
new file mode 100644
index 00000000..2f1784c1
--- /dev/null
+++ b/agentuniverse/agent/plan/planner/planner.py
@@ -0,0 +1,164 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+# @Time    : 2024/3/13 10:42
+# @Author  : heji
+# @Email   : lc299034@antgroup.com
+# @FileName: planner.py
+"""Base class for Planner."""
+import json
+from abc import abstractmethod
+from typing import Optional, List
+
+from langchain_core.memory import BaseMemory
+from langchain_core.prompts import PromptTemplate
+
+from agentuniverse.agent.action.knowledge.knowledge import Knowledge
+from agentuniverse.agent.action.knowledge.knowledge_manager import KnowledgeManager
+from agentuniverse.agent.action.knowledge.store.document import Document
+from agentuniverse.agent.action.knowledge.store.query import Query
+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.memory import Memory
+from agentuniverse.agent.memory.message import Message
+from agentuniverse.agent.memory.memory_manager import MemoryManager
+from agentuniverse.base.component.component_base import ComponentBase
+from agentuniverse.base.component.component_enum import ComponentEnum
+from agentuniverse.base.config.component_configer.configers.planner_configer import PlannerConfiger
+from agentuniverse.llm.llm import LLM
+from agentuniverse.llm.llm_manager import LLMManager
+from agentuniverse.prompt.prompt import Prompt
+from agentuniverse.base.util.memory_util import generate_messages
+
+
+class Planner(ComponentBase):
+    """
+    Base class for all planners.
+
+    All planners should inherit from this class
+    """
+    name: Optional[str] = None
+    description: Optional[str] = None
+    output_key: str = 'output'
+    input_key: str = 'input'
+    prompt_assemble_order: list = ['introduction', 'target', 'instruction']
+    prompt: Prompt = Prompt()
+
+    def __init__(self):
+        """Initialize the ComponentBase."""
+        super().__init__(component_type=ComponentEnum.PLANNER)
+
+    @abstractmethod
+    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): Agent input object.
+        Returns:
+            dict: The planner result.
+        """
+        pass
+
+    def handle_memory(self, agent_model: AgentModel, planner_input: dict) -> BaseMemory | None:
+        """Memory module processing.
+
+        Args:
+            agent_model (AgentModel): Agent model object.
+            planner_input (dict): Planner input object.
+        Returns:
+             Memory: The memory.
+        """
+        chat_history: list = planner_input.get('chat_history')
+        memory_name = agent_model.memory.get('name')
+        llm_model = agent_model.memory.get('llm_model') or dict()
+        llm_name = llm_model.get('name')
+
+        messages: list[Message] = generate_messages(chat_history)
+        llm: LLM = LLMManager().get_instance_obj(llm_name) if llm_name else None
+        params: dict = dict()
+        params['messages'] = messages
+        params['llm'] = llm
+        params['input_key'] = self.input_key
+        params['output_key'] = self.output_key
+
+        memory: Memory = MemoryManager().get_instance_obj(memory_name)
+        if memory is None:
+            return None
+        memory.set_by_agent_model(**params)
+        langchain_memory: BaseMemory = memory.as_langchain()
+
+        planner_input['chat_history'] = langchain_memory.load_memory_str
+        return langchain_memory
+
+    def handle_action(self, agent_model: AgentModel, planner_input: dict, input_object: InputObject):
+        """Tool or knowledge processing.
+
+        Args:
+            agent_model (AgentModel): Agent model object.
+            planner_input (dict): Planner input object.
+            input_object (InputObject): Agent input object.
+        """
+        action: dict = agent_model.action or dict()
+        tools: list = action.get('tool') or list()
+        knowledge: list = action.get('knowledge') or list()
+
+        action_result: list = list()
+
+        for tool_name in tools:
+            tool = ToolManager().get_instance_obj(tool_name)
+            if tool is None:
+                continue
+            tool_input = {key: input_object.get_data(key) for key in tool.input_keys}
+            action_result.append(tool.run(**tool_input))
+
+        for knowledge_name in knowledge:
+            knowledge: Knowledge = KnowledgeManager().get_instance_obj(knowledge_name)
+            if knowledge is None:
+                continue
+            knowledge_res: List[Document] = knowledge.store.query(
+                Query(query_str=input_object.get_data(self.input_key), similarity_top_k=2), **input_object.to_dict())
+            for document in knowledge_res:
+                action_result.append(document.text)
+
+        planner_input['background'] = planner_input['background'] or '' + "\n".join(action_result)
+
+    def handle_prompt(self, agent_model: AgentModel, planner_input: dict):
+        """Prompt module processing.
+
+        Args:
+            agent_model (AgentModel): Agent model object.
+            planner_input (dict): Planner input object.
+        Returns:
+            PromptTemplate: The prompt template.
+        """
+        pass
+
+    def handle_llm(self, agent_model: AgentModel) -> LLM:
+        """Language model module processing.
+
+        Args:
+            agent_model (AgentModel): Agent model object.
+        Returns:
+            LLM: The language model.
+        """
+        llm_name = agent_model.profile.get('llm_model').get('name')
+        llm: LLM = LLMManager().get_instance_obj(llm_name)
+        llm.set_by_agent_model(**agent_model.profile.get('llm_model'))
+        return llm
+
+    def initialize_by_component_configer(self, component_configer: PlannerConfiger) -> 'Planner':
+        """Initialize the planner by the PlannerConfiger object.
+
+        Args:
+            component_configer(PlannerConfiger): the PlannerConfiger object
+        Returns:
+            Planner: the planner object
+        """
+        self.name = component_configer.name
+        self.description = component_configer.description
+        self.input_key = component_configer.input_key or self.input_key
+        self.output_key = component_configer.output_key or self.output_key
+        return self
diff --git a/agentuniverse/agent/plan/planner/planner_manager.py b/agentuniverse/agent/plan/planner/planner_manager.py
new file mode 100644
index 00000000..51030e67
--- /dev/null
+++ b/agentuniverse/agent/plan/planner/planner_manager.py
@@ -0,0 +1,19 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+# @Time    : 2024/3/13 11:04
+# @Author  : heji
+# @Email   : lc299034@antgroup.com
+# @FileName: planner_manager.py
+"""Planner Management Class."""
+from agentuniverse.base.annotation.singleton import singleton
+from agentuniverse.base.component.component_enum import ComponentEnum
+from agentuniverse.base.component.component_manager_base import ComponentManagerBase
+
+
+@singleton
+class PlannerManager(ComponentManagerBase):
+    """The PlannerManager class, which is used to manage the planners."""
+
+    def __init__(self):
+        """Initialize the PlannerManager."""
+        super().__init__(ComponentEnum.PLANNER)
diff --git a/agentuniverse/agent/plan/planner/planning_planner/__init__.py b/agentuniverse/agent/plan/planner/planning_planner/__init__.py
new file mode 100644
index 00000000..87f419a5
--- /dev/null
+++ b/agentuniverse/agent/plan/planner/planning_planner/__init__.py
@@ -0,0 +1,6 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+# @Time    : 2024/3/14 16:02
+# @Author  : heji
+# @Email   : lc299034@antgroup.com
+# @FileName: __init__.py.py
diff --git a/agentuniverse/agent/plan/planner/planning_planner/default_cn_prompt.yaml b/agentuniverse/agent/plan/planner/planning_planner/default_cn_prompt.yaml
new file mode 100644
index 00000000..4f82ce34
--- /dev/null
+++ b/agentuniverse/agent/plan/planner/planning_planner/default_cn_prompt.yaml
@@ -0,0 +1,30 @@
+introduction: 你是一位精通信息分析的ai助手。
+target: 你的目标是对需要回答的问题进行拆解，生成多个子问题。
+instruction: |
+  根据需要回答的问题，给出一个逻辑递进的思考链路，帮助用户逐渐掌握知识并最终回答问题。
+  思考链路以子问题的形式体现，每个子问题都是一个完整的句子。
+  思考链路必须严格遵循需要回答的问题，不可以延伸问题，也不可以直接回答问题。
+  这个思考链路的每一步必须是简单、单一的。
+  复杂问题必须拆解成多个步骤。
+  每一步的问题必须是有答案的，不能是开放性的问题。
+  每一步的问题必须是完整的句子，不能有任何歧义。
+  请将这个问题拆解为多步，每一步不可以和原始问题相同，一步一步来。
+  
+  输出必须是按照以下格式化的Json代码片段，thought字段代表拆解问题的思考过程，framework字段代表拆解后的子问题列表。
+  {{
+      "thought": string,
+      "framework": list
+  }}
+  
+  之前的对话:
+  {chat_history}
+  
+  背景信息是:
+  {background}
+  
+  开始!
+  必须使用中文回答用户提出的问题。
+  需要回答的问题是: {input}
+metadata:
+  type: 'PROMPT'
+  version: 'planning_planner.default_cn'
diff --git a/agentuniverse/agent/plan/planner/planning_planner/default_en_prompt.yaml b/agentuniverse/agent/plan/planner/planning_planner/default_en_prompt.yaml
new file mode 100644
index 00000000..8029a09d
--- /dev/null
+++ b/agentuniverse/agent/plan/planner/planning_planner/default_en_prompt.yaml
@@ -0,0 +1,30 @@
+introduction: You are an AI assistant proficient in information analysis.
+target: Your goal is to break down the questions that need to be answered and generate multiple sub-questions.
+instruction: |
+  Depending on the question to be answered, a logical progression of thinking is given to help the user gradually acquire knowledge and eventually answer the question.
+  The chain of thought is represented in the form of sub-questions, each of which is a complete sentence.
+  The chain of thought must strictly follow the question to be answered, without extending the question or answering it directly.
+  Each step of this thinking chain must be simple and singular.
+  Complex questions must be broken down into multiple steps.
+  The question at each step must have an answer and cannot be an open-ended question.
+  The questions at each step must be complete sentences with no ambiguity.
+  Please break this question down into multiple steps, each step must not be the same as the original question, one step at a time.
+  
+  The output must be a Json code snippet formatted according to the following, with the thought field representing the thought process of the disassembled problem and the framework field representing the list of disassembled sub-problems.
+  {{
+  "thought": string,
+  "framework": list
+  }}
+  
+  Previous conversations.
+  {chat_history}
+  
+  Background information is.
+  {background}
+  
+  Start!
+  You must answer user questions in English.
+  The question that needs to be answered is: {input}
+metadata:
+  type: 'PROMPT'
+  version: 'planning_planner.default_en'
diff --git a/agentuniverse/agent/plan/planner/planning_planner/planning_planner.py b/agentuniverse/agent/plan/planner/planning_planner/planning_planner.py
new file mode 100644
index 00000000..220a1403
--- /dev/null
+++ b/agentuniverse/agent/plan/planner/planning_planner/planning_planner.py
@@ -0,0 +1,77 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+# @Time    : 2024/3/14 16:02
+# @Author  : heji
+# @Email   : lc299034@antgroup.com
+# @FileName: planning_planner.py
+"""Planning planner module."""
+import asyncio
+from langchain.chains import LLMChain
+from langchain_core.memory import BaseMemory
+
+from agentuniverse.agent.agent_model import AgentModel
+from agentuniverse.agent.input_object import InputObject
+from agentuniverse.agent.plan.planner.planner import Planner
+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 PlanningPlanner(Planner):
+    """Planning 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): Agent input object.
+        Returns:
+            dict: The planner result.
+        """
+        memory: BaseMemory = self.handle_memory(agent_model, planner_input)
+
+        llm: LLM = self.handle_llm(agent_model)
+
+        self.handle_prompt(agent_model, planner_input)
+
+        llm_chain = LLMChain(llm=llm.as_langchain(),
+                             prompt=self.prompt.as_langchain(),
+                             output_key=self.output_key, memory=memory)
+
+        return asyncio.run(llm_chain.acall(planner_input))
+
+    def handle_prompt(self, agent_model: AgentModel, planner_input: dict):
+        """Prompt module processing.
+
+        Args:
+            agent_model (AgentModel): Agent model object.
+            planner_input (dict): Planner input object.
+        Returns:
+            PromptTemplate: The prompt template.
+        """
+        expert_framework = planner_input.pop('expert_framework', '') or ''
+
+        profile: dict = agent_model.profile
+
+        origin_instruction = profile.get('instruction')
+        user_instruction = expert_framework + origin_instruction if origin_instruction else origin_instruction
+
+        user_prompt_model: AgentPromptModel = AgentPromptModel(introduction=profile.get('introduction'),
+                                                               target=profile.get('target'),
+                                                               instruction=user_instruction)
+
+        # get the prompt by the prompt version
+        prompt_version: str = profile.get('prompt_version') or 'planning_planner.default_cn'
+        prompt: Prompt = PromptManager().get_instance_obj(prompt_version)
+
+        system_prompt_model: AgentPromptModel = AgentPromptModel(introduction=prompt.introduction,
+                                                                 target=prompt.target,
+                                                                 instruction=expert_framework + prompt.instruction)
+        self.prompt.build_prompt(user_prompt_model, system_prompt_model,
+                                 self.prompt_assemble_order)
+        process_llm_token(self.prompt.as_langchain(), profile, planner_input)
diff --git a/agentuniverse/agent/plan/planner/planning_planner/planning_planner.yaml b/agentuniverse/agent/plan/planner/planning_planner/planning_planner.yaml
new file mode 100644
index 00000000..94c0d1ff
--- /dev/null
+++ b/agentuniverse/agent/plan/planner/planning_planner/planning_planner.yaml
@@ -0,0 +1,6 @@
+name: 'planning_planner'
+description: 'planning planner'
+metadata:
+  type: 'PLANNER'
+  module: 'agentuniverse.agent.plan.planner.planning_planner.planning_planner'
+  class: 'PlanningPlanner'
\ No newline at end of file
diff --git a/agentuniverse/agent/plan/planner/rag_planner/__init__.py b/agentuniverse/agent/plan/planner/rag_planner/__init__.py
new file mode 100644
index 00000000..e435ed17
--- /dev/null
+++ b/agentuniverse/agent/plan/planner/rag_planner/__init__.py
@@ -0,0 +1,6 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+# @Time    : 2024/3/25 14:56
+# @Author  : heji
+# @Email   : lc299034@antgroup.com
+# @FileName: __init__.py.py
diff --git a/agentuniverse/agent/plan/planner/rag_planner/default_cn_prompt.yaml b/agentuniverse/agent/plan/planner/rag_planner/default_cn_prompt.yaml
new file mode 100644
index 00000000..3f4adbc6
--- /dev/null
+++ b/agentuniverse/agent/plan/planner/rag_planner/default_cn_prompt.yaml
@@ -0,0 +1,24 @@
+introduction: 你是一位精通信息分析的ai助手。
+target: 你的目标是根据用户的问题以及给出的背景信息给出答案。
+instruction: |
+  你需要遵守的规则是:
+  1. 必须使用中文回答用户提出的问题。
+  2. 答案的字数控制在300字以内。
+  3. 不采用背景信息中的错误信息。
+  4. 要考虑答案和问题的相关性，不做对问题没有帮助的回答。
+  5. 简明扼要，重点突出，从不过多花哨词藻。
+  6. 不说模糊的推测。
+  7. 尽量多的使用数值类信息。
+
+  之前的对话:
+  {chat_history}
+
+  背景信息是:
+  {background}
+
+  开始!
+
+  需要回答的问题是: {input}
+metadata:
+  type: 'PROMPT'
+  version: 'rag_planner.default_cn'
diff --git a/agentuniverse/agent/plan/planner/rag_planner/default_en_prompt.yaml b/agentuniverse/agent/plan/planner/rag_planner/default_en_prompt.yaml
new file mode 100644
index 00000000..cbd8d503
--- /dev/null
+++ b/agentuniverse/agent/plan/planner/rag_planner/default_en_prompt.yaml
@@ -0,0 +1,24 @@
+introduction: You are an AI assistant proficient in information analysis.
+target: Your goal is to provide answers based on the user's questions and the background information provided.
+instruction: |
+  The rules you need to follow are:
+  1. You must answer user questions in English.
+  2. Keep your answers within 300 characters.
+  3. Do not use incorrect information from the background.
+  4. Consider the relevance of the answer to the question and avoid unhelpful responses.
+  5. Be concise, focused, and avoid excessive use of fancy words.
+  6. Avoid making vague guesses.
+  7. Use numerical information whenever possible.
+  
+  Previous conversation:
+  {chat_history}
+  
+  Background information:
+  {background}
+  
+  Let's get started!
+  
+  The question that needs to be answered is: {input}
+metadata:
+  type: 'PROMPT'
+  version: 'rag_planner.default_en'
diff --git a/agentuniverse/agent/plan/planner/rag_planner/rag_planner.py b/agentuniverse/agent/plan/planner/rag_planner/rag_planner.py
new file mode 100644
index 00000000..3b5bdf2b
--- /dev/null
+++ b/agentuniverse/agent/plan/planner/rag_planner/rag_planner.py
@@ -0,0 +1,73 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+# @Time    : 2024/3/25 14:58
+# @Author  : heji
+# @Email   : lc299034@antgroup.com
+# @FileName: rag_planner.py
+"""Rag planner module."""
+import asyncio
+from langchain.chains import LLMChain
+from langchain_core.memory import BaseMemory
+from agentuniverse.agent.agent_model import AgentModel
+from agentuniverse.agent.input_object import InputObject
+from agentuniverse.agent.plan.planner.planner import Planner
+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 RagPlanner(Planner):
+    """Rag 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): Agent input object.
+        Returns:
+            dict: The planner result.
+        """
+        memory: BaseMemory = self.handle_memory(agent_model, planner_input)
+
+        self.handle_action(agent_model, planner_input, input_object)
+
+        llm: LLM = self.handle_llm(agent_model)
+
+        self.handle_prompt(agent_model, planner_input)
+
+        llm_chain = LLMChain(llm=llm.as_langchain(),
+                             prompt=self.prompt.as_langchain(),
+                             output_key=self.output_key, memory=memory)
+        return asyncio.run(llm_chain.acall(inputs=planner_input))
+
+    def handle_prompt(self, agent_model: AgentModel, planner_input: dict):
+        """Prompt module processing.
+
+        Args:
+            agent_model (AgentModel): Agent model object.
+            planner_input (dict): Planner input object.
+        Returns:
+            PromptTemplate: The prompt template.
+        """
+        profile: dict = agent_model.profile
+
+        user_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') or 'rag_planner.default_cn'
+        prompt: Prompt = PromptManager().get_instance_obj(prompt_version)
+
+        system_prompt_model: AgentPromptModel = AgentPromptModel(introduction=prompt.introduction,
+                                                                 target=prompt.target,
+                                                                 instruction=prompt.instruction)
+
+        self.prompt.build_prompt(user_prompt_model, system_prompt_model,
+                                 self.prompt_assemble_order)
+        process_llm_token(self.prompt.as_langchain(), profile, planner_input)
diff --git a/agentuniverse/agent/plan/planner/rag_planner/rag_planner.yaml b/agentuniverse/agent/plan/planner/rag_planner/rag_planner.yaml
new file mode 100644
index 00000000..58bb4c9d
--- /dev/null
+++ b/agentuniverse/agent/plan/planner/rag_planner/rag_planner.yaml
@@ -0,0 +1,6 @@
+name: 'rag_planner'
+description: 'rag planner'
+metadata:
+  type: 'PLANNER'
+  module: 'agentuniverse.agent.plan.planner.rag_planner.rag_planner'
+  class: 'RagPlanner'
\ No newline at end of file
diff --git a/agentuniverse/agent/plan/planner/reviewing_planner/__init__.py b/agentuniverse/agent/plan/planner/reviewing_planner/__init__.py
new file mode 100644
index 00000000..8390425d
--- /dev/null
+++ b/agentuniverse/agent/plan/planner/reviewing_planner/__init__.py
@@ -0,0 +1,6 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+# @Time    : 2024/3/18 10:55
+# @Author  : heji
+# @Email   : lc299034@antgroup.com
+# @FileName: __init__.py.py
diff --git a/agentuniverse/agent/plan/planner/reviewing_planner/default_cn_prompt.yaml b/agentuniverse/agent/plan/planner/reviewing_planner/default_cn_prompt.yaml
new file mode 100644
index 00000000..c40559af
--- /dev/null
+++ b/agentuniverse/agent/plan/planner/reviewing_planner/default_cn_prompt.yaml
@@ -0,0 +1,28 @@
+introduction: 你是一位精通信息分析的ai助手。
+target: 你的目标是判断问题对应的答案是否提供了有价值的信息，并对问题的答案做出建议和评价。
+instruction: |
+  你的工作是对用户根据指定问题给出的答案内容，判断答案是否有用并且给出具体的评价和建议。
+  
+  你需要遵守以下规则:
+  1.回答必须是完整回答了我的问题，才是有用的。
+  2.回答如果是给出了一种查询信息的方式，是无用的。
+  --------------------------------------------------------------------------------------------------------------------------
+  输出必须是按照以下格式化的Json代码片段，suggestion字段是判断这个回答对问题是否有用的思考过程，is_useful字段是判断这个回答对问题是否有用的结果。
+  {{
+      "suggestion": string,
+      "is_useful": true/false
+  }}
+  
+  之前的对话:
+  {chat_history}
+  
+  背景信息是:
+  {background}
+  
+  开始!
+  必须使用中文回答用户提出的问题。
+  指定的问题是: {input}
+  给出的答案是: {expressing_result}
+metadata:
+  type: 'PROMPT'
+  version: 'reviewing_planner.default_cn'
diff --git a/agentuniverse/agent/plan/planner/reviewing_planner/default_en_prompt.yaml b/agentuniverse/agent/plan/planner/reviewing_planner/default_en_prompt.yaml
new file mode 100644
index 00000000..516a9403
--- /dev/null
+++ b/agentuniverse/agent/plan/planner/reviewing_planner/default_en_prompt.yaml
@@ -0,0 +1,28 @@
+introduction: You are an AI assistant proficient in information analysis.
+target: Your goal is to determine whether the answer to a question provides valuable information and provide suggestions and evaluations for the answer.
+instruction: |
+  Your job is to evaluate the answer provided by users based on the specified question, determine its usefulness, and provide specific feedback and suggestions.
+  
+  You need to follow these rules:
+  1. An answer is only considered useful if it fully addresses my question.
+  2. If an answer provides a way to search for information, it is considered useless.
+  --------------------------------------------------------------------------------------------------------------------------
+  The output must be in the following formatted JSON code snippet. The "suggestion" field represents the thought process of determining whether the answer is useful for the question, and the "is_useful" field indicates the result of judging whether the answer is useful for the question.
+  {{
+      "suggestion": string,
+      "is_useful": true/false
+  }}
+  
+  Previous conversation:
+  {chat_history}
+  
+  Background information:
+  {background}
+  
+  Let's begin!
+  You must answer user questions in English.
+  The specified question is: {input}
+  The provided answer is: {expressing_result}
+metadata:
+  type: 'PROMPT'
+  version: 'reviewing_planner.default_en'
diff --git a/agentuniverse/agent/plan/planner/reviewing_planner/reviewing_planner.py b/agentuniverse/agent/plan/planner/reviewing_planner/reviewing_planner.py
new file mode 100644
index 00000000..c16bb617
--- /dev/null
+++ b/agentuniverse/agent/plan/planner/reviewing_planner/reviewing_planner.py
@@ -0,0 +1,77 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+# @Time    : 2024/3/18 10:55
+# @Author  : heji
+# @Email   : lc299034@antgroup.com
+# @FileName: reviewing_planner.py
+"""Reviewing planner module."""
+import asyncio
+from langchain.chains import LLMChain
+from langchain_core.memory import BaseMemory
+from langchain_core.prompts import PromptTemplate
+from agentuniverse.agent.agent_model import AgentModel
+from agentuniverse.agent.input_object import InputObject
+from agentuniverse.agent.plan.planner.planner import Planner
+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 ReviewingPlanner(Planner):
+    """Reviewing 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): Agent input object.
+        Returns:
+            dict: The planner result.
+        """
+        memory: BaseMemory = self.handle_memory(agent_model, planner_input)
+
+        llm: LLM = self.handle_llm(agent_model)
+
+        self.handle_prompt(agent_model, planner_input)
+
+        llm_chain = LLMChain(llm=llm.as_langchain(),
+                             prompt=self.prompt.as_langchain(),
+                             output_key=self.output_key, memory=memory)
+
+        return asyncio.run(llm_chain.acall(inputs=planner_input))
+
+    def handle_prompt(self, agent_model: AgentModel, planner_input: dict):
+        """Generate prompt template for the planner.
+
+        Args:
+            agent_model (AgentModel): The agent model.
+            planner_input (dict): The agent input.
+        Returns:
+            PromptTemplate: The prompt template.
+        """
+        expert_framework = planner_input.pop('expert_framework', '') or ''
+
+        profile: dict = agent_model.profile
+
+        origin_instruction = profile.get('instruction')
+        user_instruction = expert_framework + origin_instruction if origin_instruction else origin_instruction
+
+        user_prompt_model: AgentPromptModel = AgentPromptModel(introduction=profile.get('introduction'),
+                                                               target=profile.get('target'),
+                                                               instruction=user_instruction)
+
+        # get the prompt by the prompt version
+        prompt_version: str = profile.get('prompt_version') or 'reviewing_planner.default_cn'
+        prompt: Prompt = PromptManager().get_instance_obj(prompt_version)
+
+        system_prompt_model: AgentPromptModel = AgentPromptModel(introduction=prompt.introduction,
+                                                                 target=prompt.target,
+                                                                 instruction=expert_framework + prompt.instruction)
+
+        self.prompt.build_prompt(user_prompt_model, system_prompt_model,
+                                 self.prompt_assemble_order)
+        process_llm_token(self.prompt.as_langchain(), profile, planner_input)
diff --git a/agentuniverse/agent/plan/planner/reviewing_planner/reviewing_planner.yaml b/agentuniverse/agent/plan/planner/reviewing_planner/reviewing_planner.yaml
new file mode 100644
index 00000000..c8c97cf0
--- /dev/null
+++ b/agentuniverse/agent/plan/planner/reviewing_planner/reviewing_planner.yaml
@@ -0,0 +1,6 @@
+name: 'reviewing_planner'
+description: 'reviewing planner'
+metadata:
+  type: 'PLANNER'
+  module: 'agentuniverse.agent.plan.planner.reviewing_planner.reviewing_planner'
+  class: 'ReviewingPlanner'
\ No newline at end of file
diff --git a/agentuniverse/agent_serve/web/dal/request_library.py b/agentuniverse/agent_serve/web/dal/request_library.py
index 6b58486e..a9cac69f 100644
--- a/agentuniverse/agent_serve/web/dal/request_library.py
+++ b/agentuniverse/agent_serve/web/dal/request_library.py
@@ -54,16 +54,8 @@ def __init__(self, configer: Configer = None):
             db_path.parent.mkdir(parents=True, exist_ok=True)
             db_uri = f'sqlite:////{db_path}'
 
-        # Create database engine
-        self.engine = create_engine(
-            db_uri,
-            _json_serializer=lambda x: json.dumps(x, ensure_ascii=False)
-        )
-        self.Session = sessionmaker(bind=self.engine)
-
-        with self.engine.connect() as conn:
-            if not conn.dialect.has_table(conn, REQUEST_TABLE_NAME):
-                Base.metadata.create_all(self.engine)
+        self.db_uri = db_uri
+        self.Session = None
 
     def query_request_by_request_id(self, request_id: str) -> RequestDO | None:
         """Get a RequestDO with given request_id.
@@ -74,7 +66,7 @@ def query_request_by_request_id(self, request_id: str) -> RequestDO | None:
         Return:
             The target RequestDO or none when no such data.
         """
-        session = self.Session()
+        session = self.__get_session()
         try:
             result = session.execute(
                 select(RequestORM).where(RequestORM.request_id == request_id)
@@ -94,7 +86,7 @@ def add_request(self, request_do: RequestDO) -> int:
         Return:
             A int stands unique data id in table.
         """
-        session = self.Session()
+        session = self.__get_session()
         try:
             request_orm = RequestORM(**request_do.model_dump())
             session.add(request_orm)
@@ -106,7 +98,7 @@ def add_request(self, request_do: RequestDO) -> int:
     def update_request(self, request_do: RequestDO):
         """Update the request data with same request id as the given
         RequestDO."""
-        session = self.Session()
+        session = self.__get_session()
         try:
             db_request_do = session.query(RequestORM).filter(
                 RequestORM.request_id == request_do.request_id).first()
@@ -121,7 +113,7 @@ def update_request(self, request_do: RequestDO):
 
     def update_gmt_modified(self, request_id: str):
         """Update the request task latest active time."""
-        session = self.Session()
+        session = self.__get_session()
         try:
             db_request_do = session.query(RequestORM).filter(
                 RequestORM.request_id == request_id).first()
@@ -132,6 +124,21 @@ def update_gmt_modified(self, request_id: str):
         finally:
             session.close()
 
+    def __get_session(self):
+        if self.Session:
+            return self.Session()
+        # Create database engine
+        self.engine = create_engine(
+            self.db_uri,
+            json_serializer=lambda x: json.dumps(x, ensure_ascii=False)
+        )
+        self.Session = sessionmaker(bind=self.engine)
+
+        with self.engine.connect() as conn:
+            if not conn.dialect.has_table(conn, REQUEST_TABLE_NAME):
+                Base.metadata.create_all(self.engine)
+        return self.Session()
+
     def __request_orm_to_do(self, request_orm: RequestORM) -> RequestDO:
         """Transfer a RequestORM to RequestDO."""
         request_obj = RequestDO(
diff --git a/agentuniverse/agent_serve/web/request_task.py b/agentuniverse/agent_serve/web/request_task.py
index bf7363a7..ce9b7a51 100644
--- a/agentuniverse/agent_serve/web/request_task.py
+++ b/agentuniverse/agent_serve/web/request_task.py
@@ -1,9 +1,9 @@
 # !/usr/bin/env python3
 # -*- coding:utf-8 -*-
 
-# @Time    : 2024/04/24 16:19
-# @Author  : weizhongjie.wezj
-# @Email   : weizhongjie.wzj@antgroup.com
+# @Time    : 2024/3/25 11:18
+# @Author  : fanen.lhy
+# @Email   : fanen.lhy@antgroup.com
 # @FileName: request_task.py
 
 import enum
@@ -233,13 +233,13 @@ def query_request_state(request_id: str) -> dict:
         """
         request_do = RequestLibrary().query_request_by_request_id(
             request_id)
-        RequestTask.is_validate(request_do)
         if request_do is None:
             return {"state": TaskStateEnum.INIT.value,
                     "result": None,
                     "steps": None}
+        RequestTask.is_validate(request_do)
         return {
             "state": request_do.state,
-            "result": request_do.result.get('result'),
+            "result": request_do.result,
             "steps": request_do.steps
         }
diff --git a/agentuniverse/agent_serve/web/rpc/__init__.py b/agentuniverse/agent_serve/web/rpc/__init__.py
new file mode 100644
index 00000000..3c8a2417
--- /dev/null
+++ b/agentuniverse/agent_serve/web/rpc/__init__.py
@@ -0,0 +1,7 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+
+# @Time    : 2024/4/19 11:47
+# @Author  : fanen.lhy
+# @Email   : fanen.lhy@antgroup.com
+# @FileName: __init__.py.py
diff --git a/agentuniverse/agent_serve/web/rpc/rpc_server.py b/agentuniverse/agent_serve/web/rpc/rpc_server.py
new file mode 100644
index 00000000..81e67e4d
--- /dev/null
+++ b/agentuniverse/agent_serve/web/rpc/rpc_server.py
@@ -0,0 +1,47 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+
+# @Time    : 2024/4/19 15:59
+# @Author  : fanen.lhy
+# @Email   : fanen.lhy@antgroup.com
+# @FileName: rpc_server.py
+
+import json
+
+from agentuniverse.agent_serve.service_instance import ServiceInstance
+from ..request_task import RequestTask
+from ..web_util import service_run_queue
+
+# TODO: RPC Agent Service API.
+
+
+def service_run(saved: bool, params: str, service_id: str):
+    if params and params.strip():
+        params = json.loads(params)
+    else:
+        params = {}
+    request_task = RequestTask(ServiceInstance(service_id).run, saved,
+                               **params)
+    result = request_task.run()
+    return {
+        "success": True,
+        "result": result,
+        "message": None,
+        "request_id": request_task.request_id
+    }
+
+
+def service_run_async(saved: bool, params: str, service_id: str):
+    if params and params.strip():
+        params = json.loads(params)
+    else:
+        params = {}
+    params['service_id'] = service_id
+    task = RequestTask(service_run_queue, saved, **params)
+    task.async_run()
+    return {
+        "success": True,
+        "result": None,
+        "message": None,
+        "request_id": task.request_id
+    }
diff --git a/agentuniverse/agent_serve/web/web_server.py b/agentuniverse/agent_serve/web/web_server.py
index 96827ace..bc7754f2 100644
--- a/agentuniverse/agent_serve/web/web_server.py
+++ b/agentuniverse/agent_serve/web/web_server.py
@@ -1,11 +1,3 @@
-# !/usr/bin/env python3
-# -*- coding:utf-8 -*-
-
-# @Time    : 2024/04/24 16:19
-# @Author  : weizhongjie.wezj
-# @Email   : weizhongjie.wzj@antgroup.com
-# @FileName: request_task.py
-
 import traceback
 
 from flask import Flask, Response
@@ -34,13 +26,14 @@ def liveness():
 
 @app.route("/service_run", methods=['POST'])
 @request_param
-def service_run(service_id: str, params: dict):
+def service_run(service_id: str, params: dict, saved: bool = False):
     """Synchronous invocation of an agent service.
 
     Request Args:
         service_id(`str`): The id of the agent service. Format like
             {appname}.service.{service_name}.
         params(`dict`): Json style params passed to service.
+        saved(`bool`): Save the request and result into database.
 
     Return:
         Returns a dict containing two keys: success and result.
@@ -50,7 +43,7 @@ def service_run(service_id: str, params: dict):
         result of the task.
     """
     params = {} if params is None else params
-    request_task = RequestTask(ServiceInstance(service_id).run, **params)
+    request_task = RequestTask(ServiceInstance(service_id).run, saved, **params)
     result = request_task.run()
     return make_standard_response(success=True, result=result,
                                   request_id=request_task.request_id)
@@ -58,20 +51,21 @@ def service_run(service_id: str, params: dict):
 
 @app.route("/service_run_stream", methods=['POST'])
 @request_param
-def service_run_stream(service_id: str, params: dict):
+def service_run_stream(service_id: str, params: dict, saved: bool = False):
     """Synchronous invocation of an agent service, return in stream form.
 
     Request Args:
         service_id(`str`): The id of the agent service. Format like
             {appname}.service.{service_name}.
         params(`dict`): Json style params passed to service.
+        saved(`bool`): Save the request and result into database.
 
     Return:
         A SSE(Server-Sent Event) stream.
     """
     params = {} if params is None else params
     params['service_id'] = service_id
-    task = RequestTask(service_run_queue, False, **params)
+    task = RequestTask(service_run_queue, saved, **params)
     response = Response(task.stream_run(), mimetype="text/event-stream")
     response.headers['X-Request-ID'] = task.request_id
     return response
@@ -79,7 +73,7 @@ def service_run_stream(service_id: str, params: dict):
 
 @app.route("/service_run_async", methods=['POST'])
 @request_param
-def service_run_async(service_id: str, params: dict):
+def service_run_async(service_id: str, params: dict, saved: bool = True):
     """Async invocation of an agent service, return the request id used to
     get result later.
 
@@ -87,6 +81,7 @@ def service_run_async(service_id: str, params: dict):
         service_id(`str`): The id of the agent service. Format like
             {appname}.service.{service_name}.
         params(`dict`): Json style params passed to service.
+        saved(`bool`): Save the request and result into database.
 
     Return:
         Returns a dict containing two keys: success and result.
@@ -102,7 +97,7 @@ def service_run_async(service_id: str, params: dict):
     """
     params = {} if params is None else params
     params['service_id'] = service_id
-    task = RequestTask(service_run_queue, **params)
+    task = RequestTask(service_run_queue, saved, **params)
     task.async_run()
     return make_standard_response(success=True,
                                   request_id=task.request_id)
diff --git a/agentuniverse/agent_serve/web/web_util.py b/agentuniverse/agent_serve/web/web_util.py
index d352d98b..24a7a65c 100644
--- a/agentuniverse/agent_serve/web/web_util.py
+++ b/agentuniverse/agent_serve/web/web_util.py
@@ -35,6 +35,12 @@ def wrapper(*args, **kwargs):
                     if key not in kwargs:
                         kwargs[key] = req_data[key]
                 continue
+            if name == "saved":
+                if "saved" in req_data:
+                    kwargs['saved'] = req_data['saved']
+                else:
+                    kwargs['saved'] = sig.parameters['saved']
+                continue
             if name == "session_id":
                 kwargs[name] = request.headers.get("X-Session-Id")
             elif param.annotation in (str, int, dict, list):
diff --git a/agentuniverse/base/agentuniverse.py b/agentuniverse/base/agentuniverse.py
index a6250efd..12c48b68 100644
--- a/agentuniverse/base/agentuniverse.py
+++ b/agentuniverse/base/agentuniverse.py
@@ -16,6 +16,7 @@
 from agentuniverse.base.config.application_configer.application_config_manager import ApplicationConfigManager
 from agentuniverse.base.config.component_configer.component_configer import ComponentConfiger
 from agentuniverse.base.component.component_configer_util import ComponentConfigerUtil
+from agentuniverse.base.config.component_configer.configers.prompt_configer import PromptConfiger
 from agentuniverse.base.config.config_type_enum import ConfigTypeEnum
 from agentuniverse.base.config.configer import Configer
 from agentuniverse.base.config.custom_configer.custom_key_configer import CustomKeyConfiger
@@ -24,11 +25,12 @@
 from agentuniverse.base.util.logging.logging_util import init_loggers
 from agentuniverse.agent_serve.web.request_task import RequestLibrary
 from agentuniverse.agent_serve.web.web_booster import GunicornApplication
+from agentuniverse.prompt.prompt_manager import PromptManager
 
 
 @singleton
 class AgentUniverse(object):
-    """agentUniverse object, responsible for the framework initialization,
+    """AgentUniverse framework object, responsible for the framework initialization,
        system variables management, etc."""
 
     def __init__(self):
@@ -38,8 +40,9 @@ def __init__(self):
 
     def start(self, config_path: str = None):
         """Start the agentUniverse framework."""
-        # step0: get default config path
+        # get default config path
         project_root_path = get_project_root_path()
+        sys.path.append(str(project_root_path.parent))
         app_path = project_root_path / 'app'
         if app_path.exists():
             sys.path.append(str(app_path))
@@ -47,33 +50,39 @@ def start(self, config_path: str = None):
             config_path = project_root_path / 'config' / 'config.toml'
             config_path = str(config_path)
 
-        # step1: load the configuration file
+        # load the configuration file
         configer = Configer(path=config_path).load()
         app_configer = AppConfiger().load_by_configer(configer)
         self.__config_container.app_configer = app_configer
 
-        # Load User custom key.
+        # load user custom key
         custom_key_configer_path = self.__parse_sub_config_path(
             configer.value.get('SUB_CONFIG_PATH', {}).get('custom_key_path'),
             config_path)
         CustomKeyConfiger(custom_key_configer_path)
 
-        # Init loguru loggers.
+        # init loguru loggers
         log_config_path = self.__parse_sub_config_path(
             configer.value.get('SUB_CONFIG_PATH', {}).get('log_config_path'),
             config_path)
         init_loggers(log_config_path)
 
-        # Init web request task database.
+        # init web request task database
         RequestLibrary(configer=configer)
 
-        # Init gunicorn web server.
+        # init gunicorn web server
         gunicorn_config_path = self.__parse_sub_config_path(
             configer.value.get('SUB_CONFIG_PATH', {})
             .get('gunicorn_config_path'), config_path)
         GunicornApplication(config_path=gunicorn_config_path)
 
-        # step2: scan and register the components
+        # init all extension module
+        ext_classes = configer.value.get('EXTENSION_MODULES', {}).get('class_list')
+        if isinstance(ext_classes, list):
+            for ext_class in ext_classes:
+                self.__dynamic_import_and_init(ext_class, configer)
+
+        # scan and register the components
         self.__scan_and_register(self.__config_container.app_configer)
 
     def __scan_and_register(self, app_configer: AppConfiger):
@@ -89,6 +98,7 @@ def __scan_and_register(self, app_configer: AppConfiger):
         core_tool_package_list = app_configer.core_tool_package_list or app_configer.core_default_package_list + self.__system_default_package
         core_service_package_list = app_configer.core_service_package_list or app_configer.core_default_package_list + self.__system_default_package
         core_memory_package_list = app_configer.core_memory_package_list or app_configer.core_default_package_list + self.__system_default_package
+        core_prompt_package_list = app_configer.core_prompt_package_list or app_configer.core_default_package_list + self.__system_default_package
 
         component_package_map = {
             ComponentEnum.AGENT: core_agent_package_list,
@@ -97,7 +107,8 @@ def __scan_and_register(self, app_configer: AppConfiger):
             ComponentEnum.PLANNER: core_planner_package_list,
             ComponentEnum.TOOL: core_tool_package_list,
             ComponentEnum.SERVICE: core_service_package_list,
-            ComponentEnum.MEMORY: core_memory_package_list
+            ComponentEnum.MEMORY: core_memory_package_list,
+            ComponentEnum.PROMPT: core_prompt_package_list
         }
 
         component_configer_list_map = {}
@@ -180,7 +191,7 @@ def __parse_sub_config_path(self, input_path: str,
                 input_path(str): Absolute or relative path of sub config file.
                 reference_file_path(str): Main config file path.
             Returns:
-                str or None: Final
+                str or None: A file path or none when no such file.
         """
         if not input_path:
             return None
@@ -193,3 +204,16 @@ def __parse_sub_config_path(self, input_path: str,
             combined_path = reference_file_path_obj.parent / input_path_obj
 
         return str(combined_path)
+
+    def __dynamic_import_and_init(self, class_path: str, configer: Configer):
+        """Resolve a sub config file path according to main config file.
+
+            Args:
+                class_path(str): Full class path like package_name.class_name.
+                Auto read from config file.
+        """
+
+        module_path, _, class_name = class_path.rpartition('.')
+        module = importlib.import_module(module_path)
+        cls = getattr(module, class_name)
+        cls(configer)
diff --git a/agentuniverse/base/component/component_configer_util.py b/agentuniverse/base/component/component_configer_util.py
index a88149e8..d230d3c6 100644
--- a/agentuniverse/base/component/component_configer_util.py
+++ b/agentuniverse/base/component/component_configer_util.py
@@ -20,11 +20,13 @@
 from agentuniverse.base.config.component_configer.configers.knowledge_configer import KnowledgeConfiger
 from agentuniverse.base.config.component_configer.configers.memory_configer import MemoryConfiger
 from agentuniverse.base.config.component_configer.configers.planner_configer import PlannerConfiger
+from agentuniverse.base.config.component_configer.configers.prompt_configer import PromptConfiger
 from agentuniverse.base.config.component_configer.configers.tool_configer import ToolConfiger
 from agentuniverse.base.config.config_type_enum import ConfigTypeEnum
 from agentuniverse.base.config.component_configer.configers.llm_configer import LLMConfiger
 from agentuniverse.base.component.component_enum import ComponentEnum
 from agentuniverse.llm.llm_manager import LLMManager
+from agentuniverse.prompt.prompt_manager import PromptManager
 
 
 class ComponentConfigerUtil(object):
@@ -38,6 +40,7 @@ class ComponentConfigerUtil(object):
         ComponentEnum.TOOL: ToolConfiger,
         ComponentEnum.MEMORY: MemoryConfiger,
         ComponentEnum.SERVICE: ServiceConfiger,
+        ComponentEnum.PROMPT: PromptConfiger,
         ComponentEnum.DEFAULT: ComponentConfiger
     }
 
@@ -48,7 +51,8 @@ class ComponentConfigerUtil(object):
         ComponentEnum.PLANNER: PlannerManager,
         ComponentEnum.TOOL: ToolManager,
         ComponentEnum.MEMORY: MemoryManager,
-        ComponentEnum.SERVICE: ServiceManager
+        ComponentEnum.SERVICE: ServiceManager,
+        ComponentEnum.PROMPT: PromptManager
     }
 
     @classmethod
diff --git a/agentuniverse/base/component/component_enum.py b/agentuniverse/base/component/component_enum.py
index 9410381f..5c88a1f0 100644
--- a/agentuniverse/base/component/component_enum.py
+++ b/agentuniverse/base/component/component_enum.py
@@ -18,6 +18,7 @@ class ComponentEnum(Enum):
     DEFAULT = "DEFAULT"
     SERVICE = "SERVICE"
     MEMORY = "MEMORY"
+    PROMPT = "PROMPT"
 
     @staticmethod
     def to_value_list():
diff --git a/agentuniverse/base/config/application_configer/app_configer.py b/agentuniverse/base/config/application_configer/app_configer.py
index 30e765c2..08b0e133 100644
--- a/agentuniverse/base/config/application_configer/app_configer.py
+++ b/agentuniverse/base/config/application_configer/app_configer.py
@@ -24,6 +24,7 @@ def __init__(self):
         self.__core_tool_package_list: Optional[list[str]] = None
         self.__core_memory_package_list: Optional[list[str]] = None
         self.__core_service_package_list: Optional[list[str]] = None
+        self.__core_prompt_package_list: Optional[list[str]] = None
 
     @property
     def base_info_appname(self) -> Optional[str]:
@@ -70,6 +71,10 @@ def core_service_package_list(self) -> Optional[list[str]]:
         """Return the service package list of the core."""
         return self.__core_service_package_list
 
+    @property
+    def core_prompt_package_list(self) -> Optional[list[str]]:
+        return self.__core_prompt_package_list
+
     def load_by_configer(self, configer: Configer) -> 'AppConfiger':
         """Load the AppConfiger by the given Configer.
 
@@ -88,4 +93,5 @@ def load_by_configer(self, configer: Configer) -> 'AppConfiger':
         self.__core_tool_package_list = configer.value.get('CORE_PACKAGE', {}).get('tool')
         self.__core_memory_package_list = configer.value.get('CORE_PACKAGE', {}).get('memory')
         self.__core_service_package_list = configer.value.get('CORE_PACKAGE', {}).get('service')
+        self.__core_prompt_package_list = configer.value.get('CORE_PACKAGE', {}).get('prompt')
         return self
diff --git a/agentuniverse/base/config/component_configer/component_configer.py b/agentuniverse/base/config/component_configer/component_configer.py
index 362e766b..6f91509c 100644
--- a/agentuniverse/base/config/component_configer/component_configer.py
+++ b/agentuniverse/base/config/component_configer/component_configer.py
@@ -35,11 +35,19 @@ def metadata_module(self) -> Optional[str]:
         """Return the module of the component."""
         return self.__metadata_module
 
+    @metadata_module.setter
+    def metadata_module(self, metadata_module: str):
+        self.__metadata_module = metadata_module
+
     @property
     def metadata_class(self) -> Optional[str]:
         """Return the class of the component."""
         return self.__metadata_class
 
+    @metadata_class.setter
+    def metadata_class(self, metadata_class: str):
+        self.__metadata_class = metadata_class
+
     def load(self) -> 'ComponentConfiger':
         """Load the configuration by the Configer object.
         Returns:
@@ -74,6 +82,3 @@ def get_component_config_type(self) -> Optional[str]:
             Optional[str]: the type of the component
         """
         return self.__metadata_type
-
-
-
diff --git a/agentuniverse/base/config/component_configer/configers/prompt_configer.py b/agentuniverse/base/config/component_configer/configers/prompt_configer.py
new file mode 100644
index 00000000..811e067d
--- /dev/null
+++ b/agentuniverse/base/config/component_configer/configers/prompt_configer.py
@@ -0,0 +1,51 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+
+# @Time    : 2024/4/22 14:45
+# @Author  : wangchongshi
+# @Email   : wangchongshi.wcs@antgroup.com
+# @FileName: prompt_configer.py
+from typing import Optional
+
+from agentuniverse.base.config.component_configer.component_configer import ComponentConfiger
+from agentuniverse.base.config.configer import Configer
+
+
+class PromptConfiger(ComponentConfiger):
+    """The PromptConfiger class, which is used to load and manage the Prompt configuration."""
+
+    def __init__(self, configer: Optional[Configer] = None):
+        """Initialize the PromptConfiger."""
+        super().__init__(configer)
+        self.__metadata_version: Optional[str] = None
+
+    @property
+    def metadata_version(self) -> Optional[str]:
+        """Return prompt version of the Prompt."""
+        return self.__metadata_version
+
+    def load(self) -> 'PromptConfiger':
+        """Load the configuration by the Configer object.
+        Returns:
+            PromptConfiger: the PromptConfiger object
+        """
+        return self.load_by_configer(self.__configer)
+
+    def load_by_configer(self, configer: Configer) -> 'PromptConfiger':
+        """Load the configuration by the Configer object.
+        Args:
+            configer(Configer): the Configer object
+        Returns:
+            PromptConfiger: the PromptConfiger object
+        """
+        super().load_by_configer(configer)
+        try:
+            self.__metadata_version = configer.value.get('metadata').get('version')
+            # set the prompt default module and class
+            if self.metadata_module is None:
+                self.metadata_module = 'agentuniverse.prompt.prompt'
+            if self.metadata_class is None:
+                self.metadata_class = 'Prompt'
+        except Exception as e:
+            raise Exception(f"Failed to parse the Prompt configuration: {e}")
+        return self
diff --git a/agentuniverse/base/prompt/__init__.py b/agentuniverse/base/prompt/__init__.py
new file mode 100644
index 00000000..645f99e4
--- /dev/null
+++ b/agentuniverse/base/prompt/__init__.py
@@ -0,0 +1,7 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+
+# @Time    : 2024/4/22 21:04
+# @Author  : wangchongshi
+# @Email   : wangchongshi.wcs@antgroup.com
+# @FileName: __init__.py.py
diff --git a/agentuniverse/base/prompt/combine_cn_prompt.yaml b/agentuniverse/base/prompt/combine_cn_prompt.yaml
new file mode 100644
index 00000000..11a19afc
--- /dev/null
+++ b/agentuniverse/base/prompt/combine_cn_prompt.yaml
@@ -0,0 +1,7 @@
+combine: |
+  写出以下由三重反引号分隔的文本的详细摘要，输出结果中需要涵盖文本的要点、数据以及任何重要的细节。
+  注意：结果输出时必须用中文。
+  ```{text}```
+metadata:
+  type: 'PROMPT'
+  version: 'prompt_processor.combine_cn'
diff --git a/agentuniverse/base/prompt/combine_en_prompt.yaml b/agentuniverse/base/prompt/combine_en_prompt.yaml
new file mode 100644
index 00000000..227dc01c
--- /dev/null
+++ b/agentuniverse/base/prompt/combine_en_prompt.yaml
@@ -0,0 +1,8 @@
+combine: |
+  Write a detailed summary of the following text separated by triple backticks.
+  And the output needs to cover the main points of the text, the data, and any important details.
+  Note: The result must be output in English.
+  ```{text}```
+metadata:
+  type: 'PROMPT'
+  version: 'prompt_processor.combine_en'
diff --git a/agentuniverse/base/prompt/summary_cn_prompt.yaml b/agentuniverse/base/prompt/summary_cn_prompt.yaml
new file mode 100644
index 00000000..f8a65746
--- /dev/null
+++ b/agentuniverse/base/prompt/summary_cn_prompt.yaml
@@ -0,0 +1,7 @@
+summary: |
+  写下这段文字的详细摘要，输出结果中需要涵盖文本的要点、数据以及任何重要的细节。
+  注意：结果输出时必须用中文。
+  {text}
+metadata:
+  type: 'PROMPT'
+  version: 'prompt_processor.summary_cn'
diff --git a/agentuniverse/base/prompt/summary_en_prompt.yaml b/agentuniverse/base/prompt/summary_en_prompt.yaml
new file mode 100644
index 00000000..856e7cc0
--- /dev/null
+++ b/agentuniverse/base/prompt/summary_en_prompt.yaml
@@ -0,0 +1,8 @@
+summary: |
+  Write a detailed summary of the text.
+  And the output needs to cover the main points of the text, the data, and any important details.
+  Note: The result must be output in English.
+  {text}
+metadata:
+  type: 'PROMPT'
+  version: 'prompt_processor.summary_en'
diff --git a/agentuniverse/base/util/prompt_util.py b/agentuniverse/base/util/prompt_util.py
index 2045e23f..26bad6b0 100644
--- a/agentuniverse/base/util/prompt_util.py
+++ b/agentuniverse/base/util/prompt_util.py
@@ -1,65 +1,51 @@
-from enum import Enum
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+
+# @Time    : 2024/4/16 14:42
+# @Author  : wangchongshi
+# @Email   : wangchongshi.wcs@antgroup.com
+# @FileName: prompt_util.py
+import asyncio
 from typing import List
+
 from langchain.chains.summarize import load_summarize_chain
-import asyncio
 from langchain_core.documents import Document
 from langchain_core.prompts import PromptTemplate
+
 from agentuniverse.llm.llm import LLM
 from agentuniverse.llm.llm_manager import LLMManager
+from agentuniverse.prompt.prompt_manager import PromptManager
 from agentuniverse.prompt.prompt_model import AgentPromptModel
+from agentuniverse.prompt.enum import PromptProcessEnum
 
 
-class PromptProcessEnum(Enum):
-    TRUNCATE = 'truncate'
-    STUFF = 'stuff'
-    MAP_REDUCE = 'map_reduce'
-
-    @classmethod
-    def from_value(cls, value):
-        for member in cls:
-            if member.value.lower() == value.lower():
-                return member
-        raise ValueError(f"No enum member with value: {value}")
-
-
-summarize_prompt_template = """
-写下这段文字的详细摘要，输出结果中需要涵盖文本的要点、数据以及任何重要的细节。
-注意：结果输出时必须用中文。
-{text}
-"""
-
-combine_prompt_template = """
-写出以下由三重反引号分隔的文本的详细摘要，输出结果中需要涵盖文本的要点、数据以及任何重要的细节。
-注意：结果输出时必须用中文。
-```{text}```
-"""
-
-summarize_prompt = PromptTemplate(template=summarize_prompt_template, input_variables=["text"])
-combine_prompt = PromptTemplate(template=combine_prompt_template, input_variables=["text"])
-
-
-def summarize_by_stuff(texts: List[str], llm: LLM):
+def summarize_by_stuff(texts: List[str], llm: LLM, summary_prompt_version: str):
     """
     stuff summarization -- general method
     """
-    stuff_chain = load_summarize_chain(llm.as_langchain(), chain_type='stuff', verbose=True, prompt=summarize_prompt)
+    summary_prompt = PromptManager().get_instance_obj(summary_prompt_version)
+    stuff_chain = load_summarize_chain(llm.as_langchain(), chain_type='stuff', verbose=True,
+                                       prompt=summary_prompt.as_langchain())
     return asyncio.run(stuff_chain.arun([Document(page_content=text) for text in texts]))
 
 
-def summarize_by_map_reduce(texts: List[str], llm: LLM, agent_llm: LLM):
+def summarize_by_map_reduce(texts: List[str], llm: LLM, agent_llm: LLM, summary_prompt_version: str,
+                            combine_prompt_version: str):
     """
     map reduce summarization -- general method
     """
     texts = split_texts(texts, agent_llm)
+    summary_prompt = PromptManager().get_instance_obj(summary_prompt_version)
+    combine_prompt = PromptManager().get_instance_obj(combine_prompt_version)
     map_reduce_chain = load_summarize_chain(llm.as_langchain(), chain_type='map_reduce', verbose=True,
-                                            map_prompt=summarize_prompt,
-                                            combine_prompt=combine_prompt)
+                                            map_prompt=summary_prompt.as_langchain(),
+                                            combine_prompt=combine_prompt.as_langchain())
     return asyncio.run(map_reduce_chain.arun([Document(page_content=text) for text in texts]))
 
 
 def split_text_on_tokens(text: str, text_token, chunk_size=800, chunk_overlap=100) -> List[str]:
     """Split incoming text and return chunks using tokenizer."""
-    # Calculate the number of characters represented by each token.
+    # calculate the number of characters represented by each token.
     char_per_token = len(text) / text_token
     chunk_char_size = int(chunk_size * char_per_token)
     chunk_char_overlap = int(chunk_overlap * char_per_token)
@@ -85,9 +71,8 @@ def split_texts(texts: list[str], agent_llm: LLM, chunk_size=800, chunk_overlap=
     """
     try:
         split_texts_res = []
-        llm = agent_llm.as_langchain()
         for text in texts:
-            text_token = llm.get_num_tokens(text)
+            text_token = agent_llm.get_num_tokens(text)
             split_texts_res.extend(
                 split_text_on_tokens(text=text, text_token=text_token, chunk_size=chunk_size,
                                      chunk_overlap=chunk_overlap))
@@ -134,29 +119,38 @@ def process_llm_token(prompt_template: PromptTemplate, profile: dict, planner_in
     llm_model: dict = profile.get('llm_model')
     llm_name: str = llm_model.get('name')
 
+    # get the prompt processor configuration
     prompt_processor: dict = llm_model.get('prompt_processor') or dict()
     prompt_processor_type: str = prompt_processor.get('type') or PromptProcessEnum.TRUNCATE.value
     prompt_processor_llm: str = prompt_processor.get('llm') or llm_name
+
+    # get the summary and combine prompt versions
+    summary_prompt_version: str = prompt_processor.get('summary_prompt_version') or 'prompt_processor.summary_cn'
+    combine_prompt_version: str = prompt_processor.get('combine_prompt_version') or 'prompt_processor.combine_cn'
+
     prompt_input_dict = {key: planner_input[key] for key in prompt_template.input_variables if key in planner_input}
 
     agent_llm: LLM = LLMManager().get_instance_obj(llm_name)
-    llm_max_tokens: int = agent_llm.max_tokens
+    # get the llm instance for prompt compression
     prompt_llm: LLM = LLMManager().get_instance_obj(prompt_processor_llm)
 
     prompt = prompt_template.format(**prompt_input_dict)
-    prompt_token_length: int = len(prompt)
+    # get the number of tokens in the prompt
+    prompt_tokens: int = agent_llm.get_num_tokens(prompt)
 
-    if prompt_token_length <= llm_max_tokens:
-        return
+    remaining_tokens = agent_llm.max_context_length() - agent_llm.max_tokens
 
-    remaining_token_length: int = prompt_token_length - llm_max_tokens
+    if prompt_tokens <= remaining_tokens:
+        return
 
     process_prompt_type_enum = PromptProcessEnum.from_value(prompt_processor_type)
 
+    # compress the background in the prompt
     content = planner_input.get('background')
     if process_prompt_type_enum == PromptProcessEnum.TRUNCATE:
-        planner_input['background'] = truncate_content(content, remaining_token_length, agent_llm)
+        planner_input['background'] = truncate_content(content, remaining_tokens, agent_llm)
     elif process_prompt_type_enum == PromptProcessEnum.STUFF:
-        planner_input['background'] = summarize_by_stuff([content], prompt_llm)
+        planner_input['background'] = summarize_by_stuff([content], prompt_llm, summary_prompt_version)
     elif process_prompt_type_enum == PromptProcessEnum.MAP_REDUCE:
-        planner_input['background'] = summarize_by_map_reduce([content], prompt_llm, agent_llm)
+        planner_input['background'] = summarize_by_map_reduce([content], prompt_llm,
+                                                              agent_llm, summary_prompt_version, combine_prompt_version)
diff --git a/agentuniverse/llm/default/__init__.py b/agentuniverse/llm/default/__init__.py
new file mode 100644
index 00000000..f5b945e0
--- /dev/null
+++ b/agentuniverse/llm/default/__init__.py
@@ -0,0 +1,7 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+
+# @Time    : 2024/4/2 16:03
+# @Author  : wangchongshi
+# @Email   : wangchongshi.wcs@antgroup.com
+# @FileName: __init__.py.py
diff --git a/agentuniverse/llm/default/default_openai_llm.py b/agentuniverse/llm/default/default_openai_llm.py
new file mode 100644
index 00000000..4de13d34
--- /dev/null
+++ b/agentuniverse/llm/default/default_openai_llm.py
@@ -0,0 +1,41 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+
+# @Time    : 2024/4/2 16:20
+# @Author  : wangchongshi
+# @Email   : wangchongshi.wcs@antgroup.com
+# @FileName: default_openai_llm.py
+from typing import Any
+
+from agentuniverse.llm.llm_output import LLMOutput
+from agentuniverse.llm.openai_llm import OpenAILLM
+
+
+class DefaultOpenAILLM(OpenAILLM):
+    """The agentUniverse default openai llm module.
+
+    LLM parameters, such as name/description/model_name/max_tokens,
+    are injected into this class by the default_openai_llm.yaml configuration.
+    """
+
+    def call(self, messages: list, **kwargs: Any) -> LLMOutput:
+        """ The call method of the LLM.
+
+        Users can customize how the model interacts by overriding call method of the LLM class.
+
+        Args:
+            messages (list): The messages to send to the LLM.
+            **kwargs: Arbitrary keyword arguments.
+        """
+        return super().call(messages, **kwargs)
+
+    async def acall(self, messages: list, **kwargs: Any) -> LLMOutput:
+        """ The async call method of the LLM.
+
+        Users can customize how the model interacts by overriding acall method of the LLM class.
+
+        Args:
+            messages (list): The messages to send to the LLM.
+            **kwargs: Arbitrary keyword arguments.
+        """
+        return await super().acall(messages, **kwargs)
diff --git a/agentuniverse/llm/default/default_openai_llm.yaml b/agentuniverse/llm/default/default_openai_llm.yaml
new file mode 100644
index 00000000..604b41eb
--- /dev/null
+++ b/agentuniverse/llm/default/default_openai_llm.yaml
@@ -0,0 +1,8 @@
+name: 'default_openai_llm'
+description: 'default openai llm with spi'
+model_name: 'gpt-3.5-turbo'
+max_tokens: 1000
+metadata:
+  type: 'LLM'
+  module: 'agentuniverse.llm.default.default_openai_llm'
+  class: 'DefaultOpenAILLM'
\ No newline at end of file
diff --git a/agentuniverse/llm/langchain_instance.py b/agentuniverse/llm/langchain_instance.py
new file mode 100644
index 00000000..a8f83901
--- /dev/null
+++ b/agentuniverse/llm/langchain_instance.py
@@ -0,0 +1,71 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+
+# @Time    : 2024/4/2 16:18
+# @Author  : wangchongshi
+# @Email   : wangchongshi.wcs@antgroup.com
+# @FileName: langchain_instance.py
+from typing import Any, List, Optional
+
+from langchain.callbacks.manager import AsyncCallbackManagerForLLMRun, CallbackManagerForLLMRun
+from langchain.chat_models import ChatOpenAI
+from langchain.schema import BaseMessage, ChatResult
+
+from agentuniverse.llm.llm import LLM
+
+
+class LangchainOpenAI(ChatOpenAI):
+    """Langchain OpenAI LLM wrapper."""
+
+    llm: Optional[LLM] = None
+
+    def __init__(self, llm: LLM):
+        """The __init__ method.
+
+        The agentUniverse LLM instance is passed to this class as an argument.
+        Convert the attributes of AgentUniverse(AU) LLM instance to the LangchainOpenAI object for initialization
+
+        Args:
+            llm (LLM): the AgentUniverse(AU) LLM instance.
+        """
+        init_params = dict()
+        init_params['model_name'] = llm.model_name if llm.model_name is not None else 'gpt-3.5-turbo'
+        init_params['temperature'] = llm.temperature if llm.temperature is not None else 0.7
+        init_params['request_timeout'] = llm.request_timeout
+        init_params['max_tokens'] = llm.max_tokens
+        init_params['max_retries'] = llm.max_retries if llm.max_retries is not None else 2
+        init_params['streaming'] = llm.streaming if llm.streaming is not None else False
+        init_params['openai_api_key'] = llm.openai_api_key
+        init_params['openai_organization'] = llm.openai_organization
+        init_params['openai_api_base'] = llm.openai_api_base
+        init_params['openai_proxy'] = llm.openai_proxy
+        super().__init__(**init_params)
+        self.llm = llm
+
+    def _generate(
+            self,
+            messages: List[BaseMessage],
+            stop: Optional[List[str]] = None,
+            run_manager: Optional[CallbackManagerForLLMRun] = None,
+            stream: Optional[bool] = None,
+            **kwargs,
+    ) -> ChatResult:
+        """Run the Langchain OpenAI LLM."""
+        message_dicts, params = self._create_message_dicts(messages, stop)
+        params = {**params, **kwargs}
+        llm_output = self.llm.call(messages=message_dicts, **params)
+        return self._create_chat_result(llm_output.raw)
+
+    async def _agenerate(
+            self,
+            messages: List[BaseMessage],
+            stop: Optional[List[str]] = None,
+            run_manager: Optional[AsyncCallbackManagerForLLMRun] = None,
+            stream: Optional[bool] = None,
+            **kwargs: Any,
+    ) -> ChatResult:
+        """Asynchronously run the Langchain OpenAI LLM."""
+        message_dicts, params = self._create_message_dicts(messages, stop)
+        params = {**params, **kwargs}
+        llm_output = await self.llm.acall(messages=message_dicts, **params)
+        return self._create_chat_result(llm_output.raw)
diff --git a/agentuniverse/llm/llm.py b/agentuniverse/llm/llm.py
new file mode 100644
index 00000000..ad09227d
--- /dev/null
+++ b/agentuniverse/llm/llm.py
@@ -0,0 +1,138 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+
+# @Time    : 2024/4/2 16:04
+# @Author  : wangchongshi
+# @Email   : wangchongshi.wcs@antgroup.com
+# @FileName: llm.py
+from abc import abstractmethod
+from typing import Optional, Any
+from langchain_core.language_models.base import BaseLanguageModel
+
+from agentuniverse.base.component.component_base import ComponentBase
+from agentuniverse.base.component.component_enum import ComponentEnum
+from agentuniverse.base.config.application_configer.application_config_manager import ApplicationConfigManager
+from agentuniverse.base.config.component_configer.configers.llm_configer import LLMConfiger
+from agentuniverse.llm.llm_output import LLMOutput
+
+
+class LLM(ComponentBase):
+    """The basic class for llm model.
+
+    Attributes:
+        client (Any): The client of the llm.
+        async_client (Any): The async client of the llm.
+        name (Optional[str]): The name of the llm class.
+        description (Optional[str]): The description of the llm model.
+        model_name (Optional[str]): The name of the llm model, such as gpt-4, gpt-3.5-turbo.
+        temperature (Optional[float]): The temperature of the llm model,
+        what sampling temperature to use, between 0 and 2.
+        request_timeout (Optional[int]): The request timeout for chat http requests.
+        max_tokens (Optional[int]): The maximum number of [tokens](/tokenizer) that can be generated in the completion.
+        streaming (Optional[bool]): Whether to stream the results or not.
+        ext_info (Optional[dict]): The extended information of the llm model.
+    """
+
+    client: Any = None
+    async_client: Any = None
+    name: Optional[str] = None
+    description: Optional[str] = None
+    model_name: Optional[str] = None
+    temperature: Optional[float] = 0.5
+    request_timeout: Optional[int] = None
+    max_tokens: Optional[int] = None
+    max_retries: Optional[int] = 2
+    streaming: Optional[bool] = False
+    ext_info: Optional[dict] = None
+
+    def __init__(self, **kwargs):
+        """Initialize the llm."""
+        super().__init__(component_type=ComponentEnum.LLM, **kwargs)
+
+    def _new_client(self):
+        """Initialize the client."""
+        pass
+
+    def _new_async_client(self):
+        """Initialize the async client."""
+        pass
+
+    @abstractmethod
+    def call(self, *args: Any, **kwargs: Any) -> LLMOutput:
+        """Run the LLM."""
+
+    @abstractmethod
+    async def acall(self, *args: Any, **kwargs: Any) -> LLMOutput:
+        """Asynchronously run the LLM."""
+
+    def as_langchain(self) -> BaseLanguageModel:
+        """Convert to the langchain llm class."""
+        pass
+
+    def get_instance_code(self) -> str:
+        """Return the full name of the llm."""
+        appname = ApplicationConfigManager().app_configer.base_info_appname
+        return f'{appname}.{self.component_type.value.lower()}.{self.name}'
+
+    def initialize_by_component_configer(self, component_configer: LLMConfiger) -> 'LLM':
+        """Initialize the LLM by the ComponentConfiger object.
+
+        Args:
+            component_configer(LLMConfiger): the ComponentConfiger object
+        Returns:
+            LLM: the LLM object
+        """
+        if component_configer.name:
+            self.name = component_configer.name
+        if component_configer.description:
+            self.description = component_configer.description
+        if component_configer.model_name:
+            self.model_name = component_configer.model_name
+        if component_configer.temperature:
+            self.temperature = component_configer.temperature
+        if component_configer.request_timeout:
+            self.request_timeout = component_configer.request_timeout
+        if component_configer.max_tokens:
+            self.max_tokens = component_configer.max_tokens
+        if component_configer.max_retries:
+            self.max_retries = component_configer.max_retries
+        if component_configer.streaming:
+            self.streaming = component_configer.streaming
+        if component_configer.ext_info:
+            self.ext_info = component_configer.ext_info
+        return self
+
+    def set_by_agent_model(self, **kwargs) -> None:
+        """ Assign values of parameters to the LLM model in the agent configuration."""
+        if 'model_name' in kwargs and kwargs['model_name']:
+            self.model_name = kwargs['model_name']
+        if 'temperature' in kwargs and kwargs['temperature']:
+            self.temperature = kwargs['temperature']
+        if 'request_timeout' in kwargs and kwargs['request_timeout']:
+            self.request_timeout = kwargs['request_timeout']
+        if 'max_tokens' in kwargs and kwargs['max_tokens']:
+            self.max_tokens = kwargs['max_tokens']
+        if 'max_retries' in kwargs and kwargs['max_retries']:
+            self.max_retries = kwargs['max_retries']
+        if 'streaming' in kwargs and kwargs['streaming']:
+            self.streaming = kwargs['streaming']
+
+    @abstractmethod
+    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.
+        """
+
+    @abstractmethod
+    def get_num_tokens(self, text: str) -> int:
+        """Get the number of tokens present in the text.
+
+        Useful for checking if an input will fit in a model's context window.
+
+        Args:
+            text: The string input to tokenize.
+
+        Returns:
+            The integer number of tokens in the text.
+        """
diff --git a/agentuniverse/llm/llm_manager.py b/agentuniverse/llm/llm_manager.py
new file mode 100644
index 00000000..603f8d27
--- /dev/null
+++ b/agentuniverse/llm/llm_manager.py
@@ -0,0 +1,19 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+
+# @Time    : 2024/4/2 16:18
+# @Author  : wangchongshi
+# @Email   : wangchongshi.wcs@antgroup.com
+# @FileName: llm_manager.py
+from agentuniverse.base.annotation.singleton import singleton
+from agentuniverse.base.component.component_enum import ComponentEnum
+from agentuniverse.base.component.component_manager_base import ComponentManagerBase
+
+
+@singleton
+class LLMManager(ComponentManagerBase):
+    """The LLMManager class, which is used to manage the LLMs."""
+
+    def __init__(self):
+        """Initialize the LLMManager."""
+        super().__init__(ComponentEnum.LLM)
diff --git a/agentuniverse/llm/llm_output.py b/agentuniverse/llm/llm_output.py
new file mode 100644
index 00000000..bc4d8112
--- /dev/null
+++ b/agentuniverse/llm/llm_output.py
@@ -0,0 +1,20 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+
+# @Time    : 2024/4/2 16:06
+# @Author  : wangchongshi
+# @Email   : wangchongshi.wcs@antgroup.com
+# @FileName: llm_output.py
+from typing import Any
+
+from pydantic import BaseModel
+
+
+class LLMOutput(BaseModel):
+    """The basic class for llm output."""
+
+    """The text of the llm output."""
+    text: str
+
+    """The raw data of the llm output."""
+    raw: Any
diff --git a/agentuniverse/llm/openai_llm.py b/agentuniverse/llm/openai_llm.py
new file mode 100644
index 00000000..719e4439
--- /dev/null
+++ b/agentuniverse/llm/openai_llm.py
@@ -0,0 +1,161 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+
+# @Time    : 2024/4/2 16:15
+# @Author  : wangchongshi
+# @Email   : wangchongshi.wcs@antgroup.com
+# @FileName: openai_llm.py
+from typing import Any, Optional
+
+import httpx
+from langchain_core.language_models.base import BaseLanguageModel
+from openai import OpenAI, AsyncOpenAI
+from pydantic import Field
+import tiktoken
+
+from agentuniverse.llm.langchain_instance import LangchainOpenAI
+from agentuniverse.llm.llm import LLM, LLMOutput
+from agentuniverse.base.util.env_util import get_from_env
+
+OPENAI_MAX_CONTEXT_LENGTH = {
+    "gpt-3.5-turbo": 4096,
+    "gpt-3.5-turbo-0301": 4096,
+    "gpt-3.5-turbo-0613": 4096,
+    "gpt-3.5-turbo-16k": 16384,
+    "gpt-3.5-turbo-16k-0613": 16384,
+    "gpt-35-turbo": 4096,
+    "gpt-35-turbo-16k": 16384,
+    "gpt-3.5-turbo-1106": 16384,
+    "gpt-4-0314": 8192,
+    "gpt-4": 8192,
+    "gpt-4-32k": 32768,
+    "gpt-4-32k-0314": 32768,
+    "gpt-4-0613": 8192,
+    "gpt-4-1106-preview": 128000,
+}
+
+
+class OpenAILLM(LLM):
+    """The openai llm class.
+
+    Attributes:
+        openai_api_key (Optional[str], optional): The API key for the OpenAI API.
+        This automatically infers the `openai_api_key` from the environment variable `OPENAI_API_KEY` if not provided.
+
+        openai_organization (Optional[str], optional): The OpenAI organization.
+        This automatically infers the `openai_organization` from the environment variable `OPENAI_ORGANIZATION` if not provided.
+
+        openai_api_base (Optional[str], optional): The OpenAI base url.
+        This automatically infers the `openai_api_base` from the environment variable `OPENAI_API_BASE` if not provided.
+
+        openai_client_args (Optional[dict], optional): Additional arguments to pass to the OpenAI client.
+   """
+
+    openai_api_key: Optional[str] = Field(default_factory=lambda: get_from_env("OPENAI_API_KEY"))
+    openai_organization: Optional[str] = Field(default_factory=lambda: get_from_env("OPENAI_ORGANIZATION"))
+    openai_api_base: Optional[str] = Field(default_factory=lambda: get_from_env("OPENAI_API_BASE"))
+    openai_proxy: Optional[str] = Field(default_factory=lambda: get_from_env("OPENAI_PROXY"))
+    openai_client_args: Optional[dict] = None
+
+    def _new_client(self):
+        """Initialize the openai client."""
+        return OpenAI(
+            api_key=self.openai_api_key,
+            organization=self.openai_organization,
+            base_url=self.openai_api_base,
+            timeout=self.request_timeout,
+            max_retries=self.max_retries,
+            http_client=httpx.Client(proxy=self.openai_proxy) if self.openai_proxy else None,
+            **(self.openai_client_args or {}),
+        )
+
+    def _new_async_client(self):
+        """Initialize the openai async client."""
+        return AsyncOpenAI(
+            api_key=self.openai_api_key,
+            organization=self.openai_organization,
+            base_url=self.openai_api_base,
+            timeout=self.request_timeout,
+            max_retries=self.max_retries,
+            http_client=httpx.AsyncClient(proxy=self.openai_proxy) if self.openai_proxy else None,
+            **(self.openai_client_args or {}),
+        )
+
+    def call(self, messages: list, **kwargs: Any) -> LLMOutput:
+        """Run the OpenAI LLM.
+
+        Args:
+            messages (list): The messages to send to the LLM.
+            **kwargs: Arbitrary keyword arguments.
+        """
+        self.client = self._new_client()
+        chat_completion = self.client.chat.completions.create(
+            messages=messages,
+            model=kwargs.pop('model', self.model_name),
+            temperature=kwargs.pop('temperature', self.temperature),
+            stream=kwargs.pop('stream', self.streaming),
+            max_tokens=kwargs.pop('max_tokens', self.max_tokens),
+            **kwargs,
+        )
+        text = chat_completion.choices[0].message.content
+        return LLMOutput(text=text, raw=chat_completion.model_dump())
+
+    async def acall(self, messages: list, **kwargs: Any) -> LLMOutput:
+        """Asynchronously run the OpenAI LLM.
+
+        Args:
+            messages (list): The messages to send to the LLM.
+            **kwargs: Arbitrary keyword arguments.
+        """
+
+        self.async_client = self._new_async_client()
+        chat_completion = await self.async_client.chat.completions.create(
+            messages=messages,
+            model=kwargs.pop('model', self.model_name),
+            temperature=kwargs.pop('temperature', self.temperature),
+            stream=kwargs.pop('stream', self.streaming),
+            max_tokens=kwargs.pop('max_tokens', self.max_tokens),
+            **kwargs,
+        )
+        text = chat_completion.choices[0].message.content
+        return LLMOutput(text=text, raw=chat_completion.model_dump())
+
+    def as_langchain(self) -> BaseLanguageModel:
+        """Convert the AgentUniverse(AU) openai llm class to the langchain openai llm class."""
+        return LangchainOpenAI(self)
+
+    def set_by_agent_model(self, **kwargs) -> None:
+        """ Assign values of parameters to the OpenAILLM model in the agent configuration."""
+        super().set_by_agent_model(**kwargs)
+        if 'openai_api_key' in kwargs and kwargs['openai_api_key']:
+            self.openai_api_key = kwargs['openai_api_key']
+        if 'openai_api_base' in kwargs and kwargs['openai_api_base']:
+            self.openai_api_base = kwargs['openai_api_base']
+        if 'openai_proxy' in kwargs and kwargs['openai_proxy']:
+            self.openai_proxy = kwargs['openai_proxy']
+        if 'openai_client_args' in kwargs and kwargs['openai_client_args']:
+            self.openai_client_args = kwargs['openai_client_args']
+
+    def max_context_length(self) -> int:
+        """Max context length.
+
+          The total length of input tokens and generated tokens is limited by the openai model's context length.
+          """
+        return OPENAI_MAX_CONTEXT_LENGTH.get(self.model_name, 4096)
+
+    def get_num_tokens(self, text: str) -> int:
+        """Get the number of tokens present in the text.
+
+        Useful for checking if an input will fit in an openai model's context window.
+
+        Args:
+            text: The string input to tokenize.
+
+        Returns:
+            The integer number of tokens in the text.
+        """
+        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/prompt/enum.py b/agentuniverse/prompt/enum.py
new file mode 100644
index 00000000..b661c5f9
--- /dev/null
+++ b/agentuniverse/prompt/enum.py
@@ -0,0 +1,23 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+
+# @Time    : 2024/4/16 14:33
+# @Author  : wangchongshi
+# @Email   : wangchongshi.wcs@antgroup.com
+# @FileName: enum.py
+import enum
+from enum import Enum
+
+
+@enum.unique
+class PromptProcessEnum(Enum):
+    TRUNCATE = 'truncate'
+    STUFF = 'stuff'
+    MAP_REDUCE = 'map_reduce'
+
+    @classmethod
+    def from_value(cls, value):
+        for member in cls:
+            if member.value.lower() == value.lower():
+                return member
+        raise ValueError(f"No enum member with value: {value}")
diff --git a/agentuniverse/prompt/prompt.py b/agentuniverse/prompt/prompt.py
new file mode 100644
index 00000000..104dd03b
--- /dev/null
+++ b/agentuniverse/prompt/prompt.py
@@ -0,0 +1,82 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+# @Time    : 2024/3/13 15:22
+# @Author  : heji
+# @Email   : lc299034@antgroup.com
+# @FileName: prompt.py
+"""Prompt base module."""
+import re
+from typing import Optional
+
+from langchain_core.prompts import PromptTemplate
+
+from agentuniverse.base.component.component_base import ComponentBase
+from agentuniverse.base.component.component_enum import ComponentEnum
+from agentuniverse.base.config.component_configer.configers.prompt_configer import PromptConfiger
+from agentuniverse.base.util.prompt_util import generate_template
+from agentuniverse.prompt.prompt_model import AgentPromptModel
+
+
+class Prompt(ComponentBase):
+    """Prompt class."""
+
+    prompt_version: Optional[str] = None
+    prompt_template: Optional[str] = None
+    input_variables: Optional[list[str]] = None
+
+    def __init__(self, **kwargs):
+        super().__init__(component_type=ComponentEnum.PROMPT, **kwargs)
+
+    def as_langchain(self) -> PromptTemplate:
+        """Convert the prompt template into a LangChain prompt template.
+
+        Returns:
+            PromptTemplate: The prompt template.
+        """
+        return PromptTemplate(template=self.prompt_template,
+                              input_variables=self.input_variables)
+
+    def build_prompt(self, user_agent_prompt_model: AgentPromptModel, system_agent_prompt_model: AgentPromptModel,
+                     prompt_assemble_order: list[str]):
+        """Build the prompt class.
+
+        Args:
+            user_agent_prompt_model (AgentPromptModel): The user agent prompt model.
+            system_agent_prompt_model (AgentPromptModel): The system agent prompt model.
+            prompt_assemble_order (list[str]): The prompt assemble ordered list.
+
+        Returns:
+            PromptTemplate: The prompt template.
+        """
+        agent_prompt_model = user_agent_prompt_model + system_agent_prompt_model
+        self.prompt_template = generate_template(agent_prompt_model, prompt_assemble_order)
+        self.input_variables = re.findall(r'\{(.*?)}', self.prompt_template)
+
+    def get_instance_code(self) -> str:
+        """Return the prompt version of the current prompt."""
+        return self.prompt_version
+
+    def initialize_by_component_configer(self, component_configer: PromptConfiger) -> 'Prompt':
+        """Initialize the prompt by the PromptConfiger object.
+
+        Args:
+            component_configer(PromptConfiger): the PromptConfiger object
+        Returns:
+            Prompt: the prompt object
+        """
+        prompt_values = []
+        for k, v in component_configer.configer.value.items():
+            # ignore metadata values
+            if k == 'metadata':
+                continue
+            self.__dict__[k] = v
+            # splice the values in the prompt configer
+            prompt_values.append(str(v))
+
+        if component_configer.metadata_version:
+            self.prompt_version = component_configer.metadata_version
+
+        self.prompt_template = '\n'.join(prompt_values)
+
+        self.input_variables = re.findall(r'\{(.*?)}', self.prompt_template)
+        return self
diff --git a/agentuniverse/prompt/prompt_manager.py b/agentuniverse/prompt/prompt_manager.py
new file mode 100644
index 00000000..fcd9f774
--- /dev/null
+++ b/agentuniverse/prompt/prompt_manager.py
@@ -0,0 +1,21 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+
+# @Time    : 2024/4/17 17:33
+# @Author  : wangchongshi
+# @Email   : wangchongshi.wcs@antgroup.com
+# @FileName: prompt_manager.py
+from agentuniverse.base.annotation.singleton import singleton
+from agentuniverse.base.component.component_enum import ComponentEnum
+from agentuniverse.base.component.component_manager_base import ComponentManagerBase
+
+
+@singleton
+class PromptManager(ComponentManagerBase):
+    """The PromptManager class, which is used to manage prompts."""
+
+    def __init__(self):
+        super().__init__(ComponentEnum.PROMPT)
+
+    def get_instance_obj(self, component_instance_name: str, appname: str = None):
+        return self._instance_obj_map.get(component_instance_name)
diff --git a/agentuniverse/prompt/prompt_model.py b/agentuniverse/prompt/prompt_model.py
new file mode 100644
index 00000000..56ff5cf7
--- /dev/null
+++ b/agentuniverse/prompt/prompt_model.py
@@ -0,0 +1,28 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+# @Time    : 2024/3/12 19:22
+# @Author  : heji
+# @Email   : lc299034@antgroup.com
+# @FileName: prompt_model.py
+"""Agent Prompt Model module."""
+from typing import Optional
+
+from pydantic import BaseModel
+
+
+class AgentPromptModel(BaseModel):
+    """Agent Prompt Model class."""
+
+    introduction: Optional[str] = None
+    target: Optional[str] = None
+    instruction: Optional[str] = None
+
+    def __add__(self, other):
+        """Merge two objects into one object."""
+        merged_object = AgentPromptModel()
+        for key in set(self.__dict__.keys()).union(other.__dict__.keys()):
+            value = getattr(self, key, None)
+            if value is None:
+                value = getattr(other, key, None)
+            setattr(merged_object, key, value)
+        return merged_object
diff --git a/docs/guidebook/_picture/agent_universe_framework_resize.jpg b/docs/guidebook/_picture/agent_universe_framework_resize.jpg
new file mode 100644
index 00000000..4613f467
Binary files /dev/null and b/docs/guidebook/_picture/agent_universe_framework_resize.jpg differ
diff --git a/pyproject.toml b/pyproject.toml
index 76943149..ffee81c9 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
 [tool.poetry]
 name = "agentUniverse"
-version = "0.0.2"
+version = "0.0.3"
 description = "agentUniverse is a framework for developing applications powered by multi-agent base on large language model."
 authors = ["AntGroup <AntGroup>"]
 readme = "README.md"
diff --git a/setup.py b/setup.py
index fd866e5f..c6ec97e5 100644
--- a/setup.py
+++ b/setup.py
@@ -29,7 +29,7 @@ def read_requirements():
                 "by multi-agent base on large language model.",
     long_description=long_description,
     long_description_content_type="text/markdown",
-    url="https://github.com/alipay/agentUniverse",
+    url="https://gitee.com/agentUniverse/agentUniverse",
     packages=setuptools.find_packages(),
     package_data={
             '': ['*.yaml'],


Test patch:
diff --git a/tests/test_agentuniverse/mock/agent_serve/__init__.py b/tests/test_agentuniverse/mock/agent_serve/__init__.py
index e69de29b..11f1b16e 100644
--- a/tests/test_agentuniverse/mock/agent_serve/__init__.py
+++ b/tests/test_agentuniverse/mock/agent_serve/__init__.py
@@ -0,0 +1,7 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+
+# @Time    : 2024/3/15 18:00
+# @Author  : fanen.lhy
+# @Email   : fanen.lhy@antgroup.com
+# @FileName: __init__.py.py
diff --git a/tests/test_agentuniverse/mock/agent_serve/mock_agent.py b/tests/test_agentuniverse/mock/agent_serve/mock_agent.py
index e69de29b..98656b11 100644
--- a/tests/test_agentuniverse/mock/agent_serve/mock_agent.py
+++ b/tests/test_agentuniverse/mock/agent_serve/mock_agent.py
@@ -0,0 +1,25 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+
+# @Time    : 2024/4/2 18:02
+# @Author  : fanen.lhy
+# @Email   : fanen.lhy@antgroup.com
+# @FileName: mock_agent.py
+
+import json
+
+
+class MockOutPut:
+    def __init__(self, output: dict):
+        self.__output = output
+
+    def to_json_str(self) -> str:
+        return json.dumps(self.__output, ensure_ascii=False)
+
+
+class MockAgent:
+    def __init__(self, run_result: dict):
+        self.__run_result = MockOutPut(run_result)
+
+    def run(self, **kwargs):
+        return self.__run_result
diff --git a/tests/test_agentuniverse/mock/agent_serve/mock_application_config_manager.py b/tests/test_agentuniverse/mock/agent_serve/mock_application_config_manager.py
index e69de29b..d92ef711 100644
--- a/tests/test_agentuniverse/mock/agent_serve/mock_application_config_manager.py
+++ b/tests/test_agentuniverse/mock/agent_serve/mock_application_config_manager.py
@@ -0,0 +1,22 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+
+# @Time    : 2024/3/18 21:03
+# @Author  : fanen.lhy
+# @Email   : fanen.lhy@antgroup.com
+# @FileName: mock_application_config_manager.py
+
+BASE_INFO_APPNAME = "test_app"
+
+
+class MockAppConfiger:
+
+    def __init__(self):
+        self.base_info_appname = BASE_INFO_APPNAME
+
+
+class MockApplicationConfigManager:
+    """Mock class of ApplicationConfigManager."""
+
+    def __init__(self):
+        self.app_configer = MockAppConfiger()
\ No newline at end of file
diff --git a/tests/test_agentuniverse/mock/agent_serve/mock_service_manager.py b/tests/test_agentuniverse/mock/agent_serve/mock_service_manager.py
index e69de29b..304a68aa 100644
--- a/tests/test_agentuniverse/mock/agent_serve/mock_service_manager.py
+++ b/tests/test_agentuniverse/mock/agent_serve/mock_service_manager.py
@@ -0,0 +1,28 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+
+# @Time    : 2024/3/18 22:53
+# @Author  : fanen.lhy
+# @Email   : fanen.lhy@antgroup.com
+# @FileName: mock_service_manager.py
+from unittest.mock import MagicMock
+
+TEST_STR = "TEST_STR"
+TEST_MOCK_SERVICE = MagicMock()
+TEST_MOCK_SERVICE.run.return_value = TEST_STR
+TEST_SERVICE_LIST = ["test_app.service.test_service"]
+TEST_SERVICE_MAP = {"test_app.service.test_service":TEST_MOCK_SERVICE}
+
+
+class ServiceManager:
+    """Mock class of agentuniverse.agent_serve.service.Service."""
+
+    def __init__(self):
+        self.__service_list: list = TEST_SERVICE_LIST
+        self.__service_map: dict = TEST_SERVICE_MAP
+
+    def get_instance_obj(self, service_code: str):
+        service_base = self.__service_map.get(service_code)
+        if service_base is None:
+            raise Exception(f"Service {service_code} not found.")
+        return service_base
diff --git a/tests/test_agentuniverse/mock/agent_serve/mock_simple_service.py b/tests/test_agentuniverse/mock/agent_serve/mock_simple_service.py
index e69de29b..08b4e76e 100644
--- a/tests/test_agentuniverse/mock/agent_serve/mock_simple_service.py
+++ b/tests/test_agentuniverse/mock/agent_serve/mock_simple_service.py
@@ -0,0 +1,17 @@
+# !/usr/bin/env python3
+# -*- coding:utf-8 -*-
+
+# @Time    : 2024/3/18 22:03
+# @Author  : fanen.lhy
+# @Email   : fanen.lhy@antgroup.com
+# @FileName: mock_simple_service.py
+
+class SimpleService:
+    """Mock class of agentuniverse.agent_serve.service.Service."""
+
+    def __init__(self, service_name: str):
+        self.service_code = SimpleService.generate_service_code(service_name)
+
+    @staticmethod
+    def generate_service_code(service_name: str) -> str:
+        return "test_app.service." + service_name
diff --git a/tests/test_agentuniverse/unit/agent/config.toml b/tests/test_agentuniverse/unit/agent/config.toml
index 1ca77e43..b26516f4 100644
--- a/tests/test_agentuniverse/unit/agent/config.toml
+++ b/tests/test_agentuniverse/unit/agent/config.toml
@@ -19,6 +19,8 @@ tool = []
 memory = []
 # Scan and register service components for all paths under this list, with priority over the default.
 service = []
+# Scan and register prompt components for all paths under this list, with priority over the default.
+prompt = []
 
 [SUB_CONFIG_PATH]
 # Log config file path, an absolute path or a relative path based on the dir where the current config file is located.
diff --git a/tests/test_agentuniverse/unit/agent/test_agent.py b/tests/test_agentuniverse/unit/agent/test_rag_agent.py
similarity index 70%
rename from tests/test_agentuniverse/unit/agent/test_agent.py
rename to tests/test_agentuniverse/unit/agent/test_rag_agent.py
index 5a143e7f..eedc6fa4 100644
--- a/tests/test_agentuniverse/unit/agent/test_agent.py
+++ b/tests/test_agentuniverse/unit/agent/test_rag_agent.py
@@ -1,9 +1,9 @@
-# !/usr/bin/env python3
 # -*- coding:utf-8 -*-
-# @Time    : 2024/3/18 15:27
-# @Author  : heji
-# @Email   : lc299034@antgroup.com
-# @FileName: test_agent.py
+
+# @Time    : 2024/4/23 14:58
+# @Author  : wangchongshi
+# @Email   : wangchongshi.wcs@antgroup.com
+# @FileName: test_rag_agent.py
 import unittest
 
 from agentuniverse.agent.agent import Agent
@@ -11,16 +11,13 @@
 from agentuniverse.agent.output_object import OutputObject
 from agentuniverse.base.agentuniverse import AgentUniverse
 
-AgentUniverse().start(config_path='./config.toml')
-
 
 class TestAgent(unittest.TestCase):
 
+    def setUp(self) -> None:
+        AgentUniverse().start(config_path='./config.toml')
+
     def test_rag_agent(self):
         instance: Agent = AgentManager().get_instance_obj('rag_agent')
         output_object: OutputObject = instance.run(input='分析下先锋领航退出中国的原因')
         print(output_object.get_data('output'))
-
-
-if __name__ == '__main__':
-    unittest.main()