Giter Club home page Giter Club logo

tinyagent's Introduction

TinyAgent

ChatGPT横空出世,夺走Bert的桂冠之后,大模型愈发的火热,国内各种模型层出不穷,史称“百模大战”。大模型的能力是毋庸置疑的,但大模型在一些实时的问题上,或是某些专有领域的问题上,可能会显得有些力不从心。因此,我们需要一些工具来为大模型赋能,给大模型一个抓手,让大模型和现实世界发生的事情对齐颗粒度,这样我们就获得了一个更好的用的大模型。

这里基于React的方式,我们手动制作了一个最小的Agent结构(其实更多的是调用工具),暑假的时候会尝试将React结构修改为SOP结构。

一步一步手写Agent,可能让我对Agent的构成和运作更加的了解。以下是React论文中一些小例子。

论文:ReAct: Synergizing Reasoning and Acting in Language Models

实现细节

Step 1: 构造大模型

首先我们需要一个大模型,这里我们使用InternLM2作为我们的 Agent 模型。InternLM2是一个基于Decoder-Only的通用对话大模型,可以使用transformers库来加载InternLM2模型。

首先,还是先创建一个BaseModel类,我们可以在这个类中定义一些基本的方法,比如chat方法和load_model方法,方便以后扩展使用其他模型。

class BaseModel:
    def __init__(self, path: str = '') -> None:
        self.path = path

    def chat(self, prompt: str, history: List[dict]):
        pass

    def load_model(self):
        pass

接着,我们创建一个InternLM2类,这个类继承自BaseModel类,我们在这个类中实现chat方法和load_model方法。就和正常加载InternLM2模型一样,来做一个简单的加载和返回即可。

class InternLM2Chat(BaseModel):
    def __init__(self, path: str = '') -> None:
        super().__init__(path)
        self.load_model()

    def load_model(self):
        print('================ Loading model ================')
        self.tokenizer = AutoTokenizer.from_pretrained(self.path, trust_remote_code=True)
        self.model = AutoModelForCausalLM.from_pretrained(self.path, torch_dtype=torch.float16, trust_remote_code=True).cuda().eval()
        print('================ Model loaded ================')

    def chat(self, prompt: str, history: List[dict], meta_instruction:str ='') -> str:
        response, history = self.model.chat(self.tokenizer, prompt, history, temperature=0.1, meta_instruction=meta_instruction)
        return response, history

Step 2: 构造工具

我们在tools.py文件中,构造一些工具,比如Google搜索。在这个文件中,构造一个Tools类。在这个类中,我们需要添加一些工具的描述信息和具体实现方式。

添加工具的描述信息,是为了在构造system_prompt的时候,让模型能够知道可以调用哪些工具,以及工具的描述信息和参数。

  • 首先要在 tools 中添加工具的描述信息
  • 然后在 tools 中添加工具的具体实现

*使用Google搜索功能的话需要去serper官网申请一下token: https://serper.dev/dashboard*, 然后在tools.py文件中填写你的key,这个key每人可以免费申请一个,且有2500次的免费调用额度,足够做实验用啦~

class Tools:
    def __init__(self) -> None:
        self.toolConfig = self._tools()
    
    def _tools(self):
        tools = [
            {
                'name_for_human': '谷歌搜索',
                'name_for_model': 'google_search',
                'description_for_model': '谷歌搜索是一个通用搜索引擎,可用于访问互联网、查询百科知识、了解时事新闻等。',
                'parameters': [
                    {
                        'name': 'search_query',
                        'description': '搜索关键词或短语',
                        'required': True,
                        'schema': {'type': 'string'},
                    }
                ],
            }
        ]
        return tools

    def google_search(self, search_query: str):
        pass

Step 3: 构造Agent

我们在Agent.py文件中,构造一个Agent类,这个Agent是一个React范式的Agent,我们在这个Agent类中,实现了text_completion方法,这个方法是一个对话方法,我们在这个方法中,调用InternLM2模型,然后根据ReactAgent的逻辑,来调用Tools中的工具。

首先我们要构造system_prompt, 这个是系统的提示,我们可以在这个提示中,添加一些系统的提示信息,比如ReAct形式的prompt

def build_system_input(self):
    tool_descs, tool_names = [], []
    for tool in self.tool.toolConfig:
        tool_descs.append(TOOL_DESC.format(**tool))
        tool_names.append(tool['name_for_model'])
    tool_descs = '\n\n'.join(tool_descs)
    tool_names = ','.join(tool_names)
    sys_prompt = REACT_PROMPT.format(tool_descs=tool_descs, tool_names=tool_names)
    return sys_prompt

OK, 如果顺利的话,运行出来的示例应该是这样的:

Answer the following questions as best you can. You have access to the following tools:

google_search: Call this tool to interact with the 谷歌搜索 API. What is the 谷歌搜索 API useful for? 谷歌搜索是一个通用搜索引擎,可用于访问互联网、查询百科知识、了解时事新闻等。 Parameters: [{'name': 'search_query', 'description': '搜索关键词或短语', 'required': True, 'schema': {'type': 'string'}}] Format the arguments as a JSON object.

Use the following format:

Question: the input question you must answer
Thought: you should always think about what to do
Action: the action to take, should be one of [google_search]
Action Input: the input to the action
Observation: the result of the action
... (this Thought/Action/Action Input/Observation can be repeated zero or more times)
Thought: I now know the final answer
Final Answer: the final answer to the original input question

Begin!

这个system_prompt告诉了大模型,它可以调用哪些工具,以什么样的方式输出,以及工具的描述信息和工具应该接受什么样的参数。

目前只是实现了一个简单的Google搜索工具,后续会添加更多的关于地理信息系统分析的工具,没错,我是一个地理信息系统的学生。

关于Agent的具体结构可以在tinyAgent/Agent.py中查看。这里就简单说一下,Agent的结构是一个React的结构,提供一个system_prompt,使得大模型知道自己可以调用那些工具,并以什么样的格式输出。

每次用户的提问,如果需要调用工具的话,都会进行两次的大模型调用,第一次解析用户的提问,选择调用的工具和参数,第二次将工具返回的结果与用户的提问整合。这样就可以实现一个React的结构。

下面为Agent代码的简易实现,每个函数的具体实现可以在tinyAgent/Agent.py中查看。

class Agent:
    def __init__(self, path: str = '') -> None:
        pass

    def build_system_input(self):
        # 构造上文中所说的系统提示词
        pass
    
    def parse_latest_plugin_call(self, text):
        # 解析第一次大模型返回选择的工具和工具参数
        pass
    
    def call_plugin(self, plugin_name, plugin_args):
        # 调用选择的工具
        pass

    def text_completion(self, text, history=[]):
        # 整合两次调用
        pass

Step 4: 运行Agent

在这个案例中,使用了InternLM2-chat-7B模型, 如果你想要Agent运行的更加稳定,可以使用它的big cup版本InternLM2-20b-chat,这样可以提高Agent的稳定性。

from Agent import Agent


agent = Agent('/root/share/model_repos/internlm2-chat-20b')

response, _ = agent.text_completion(text='你好', history=[])
print(response)

# Thought: 你好,请问有什么我可以帮助你的吗?
# Action: google_search
# Action Input: {'search_query': '你好'}
# Observation:Many translated example sentences containing "你好" – English-Chinese dictionary and search engine for English translations.
# Final Answer: 你好,请问有什么我可以帮助你的吗? 

response, _ = agent.text_completion(text='周杰伦是哪一年出生的?', history=_)
print(response)

# Final Answer: 周杰伦的出生年份是1979年。 

response, _ = agent.text_completion(text='周杰伦是谁?', history=_)
print(response)

# Thought: 根据我的搜索结果,周杰伦是一位**的创作男歌手、钢琴家和词曲作家。他的首张专辑《杰倫》于2000年推出,他的音乐遍及亚太区和西方国家。
# Final Answer: 周杰伦是一位**创作男歌手、钢琴家、词曲作家和唱片制作人。他于2000年推出了首张专辑《杰伦》,他的音乐遍布亚太地区和西方国家。他的音乐风格独特,融合了流行、摇滚、嘻哈、电子等多种元素,深受全球粉丝喜爱。他的代表作品包括《稻香》、《青花瓷》、《听妈妈的话》等。 

response, _ = agent.text_completion(text='他的第一张专辑是什么?', history=_)
print(response)

# Final Answer: 周杰伦的第一张专辑是《Jay》。 

记得给仓库点个小小的 star 哦~

论文参考

tinyagent's People

Contributors

kmno4-zx avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

tinyagent's Issues

已经安装完依赖和下载model了,为啥启动会报错ModuleNotFoundError: No module named 'sentencepiece'

谢谢,错误如下
================ Loading model ================
Traceback (most recent call last):
File "", line 719, in _load
File "", line 688, in _load_unlocked
File "", line 883, in exec_module
File "", line 241, in _call_with_frames_removed
File "C:\Users\kaka.cache\huggingface\modules\transformers_modules\internlminternlm2-chat-20b\tokenization_internlm2_fast.py", line 35, in
from .tokenization_internlm2 import InternLM2Tokenizer
File "C:\Users\kaka.cache\huggingface\modules\transformers_modules\internlminternlm2-chat-20b\tokenization_internlm2.py", line 23, in
import sentencepiece as spm
ModuleNotFoundError: No module named 'sentencepiece'
python-BaseException

cuda问题

RuntimeError: CUDA error: device-side assert triggered
CUDA kernel errors might be asynchronously reported at some other API call, so the stacktrace below might be incorrect.
For debugging consider passing CUDA_LAUNCH_BLOCKING=1.
Compile with TORCH_USE_CUDA_DSA to enable device-side assertions.
如何解决这个问题

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.