【项目实训】利用glm3-6b的function cal功能实现格式化输出

首先更改官方给出的工具注册 tool_register.py

注册function call

"""
这段代码是工具注册的部分,通过注册工具,让模型实现工具调用
"""
import inspect
import traceback
from copy import deepcopy
from pprint import pformat
from types import GenericAlias
from typing import get_origin, Annotated

_TOOL_HOOKS = {}
_TOOL_DESCRIPTIONS = {}


def register_tool(func: callable):
    tool_name = func.__name__
    tool_description = inspect.getdoc(func).strip()
    python_params = inspect.signature(func).parameters
    tool_params = []
    for name, param in python_params.items():
        annotation = param.annotation
        if annotation is inspect.Parameter.empty:
            raise TypeError(f"Parameter `{name}` missing type annotation")
        if get_origin(annotation) != Annotated:
            raise TypeError(f"Annotation type for `{name}` must be typing.Annotated")

        typ, (description, required) = annotation.__origin__, annotation.__metadata__
        typ: str = str(typ) if isinstance(typ, GenericAlias) else typ.__name__
        if not isinstance(description, str):
            raise TypeError(f"Description for `{name}` must be a string")
        if not isinstance(required, bool):
            raise TypeError(f"Required for `{name}` must be a bool")

        tool_params.append({
            "name": name,
            "description": description,
            "type": typ,
            "required": required
        })
    tool_def = {
        "name": tool_name,
        "description": tool_description,
        "params": tool_params
    }

    print("[registered tool] " + pformat(tool_def))
    _TOOL_HOOKS[tool_name] = func
    _TOOL_DESCRIPTIONS[tool_name] = tool_def

    return func


def dispatch_tool(tool_name: str, tool_params: dict) -> str:
    if tool_name not in _TOOL_HOOKS:
        return f"Tool `{tool_name}` not found. Please use a provided tool."
    tool_call = _TOOL_HOOKS[tool_name]
    try:
        ret = tool_call(**tool_params)
    except:
        ret = traceback.format_exc()
    return str(ret)


def get_tools() -> dict:
    return deepcopy(_TOOL_DESCRIPTIONS)


# tools Definitions

@register_tool
def get_interview_question_types(
    question_types: Annotated[list, '由面试过程中可能会出现的问题类型所组成的列表', True]
) -> dict:
    """
    获取面试中的问题类型,例如:个人信息、技术问题、项目经历等
    """
    if not isinstance(question_types, list):
        raise TypeError("Questions type must be a list")
    res = {'types': []}
    for t in question_types:
        res['types'].append(str(t))
    return res

我在其中定义了一个 get_interview_question_types 的方法,用于获取在面试过程中可能会出现的问题类型所组成的列表

注意!此处一定要按照官方提供的格式,对自己定义的方法进行注释,在此程序中,可以直接根据函数的自动注释生成function call中对function的描述性信息。

将function call在对话中传给大模型

与大模型对话时,调用 get_tools() 获取你定义过的方法,作为system的参数

tools = get_tools()
system = {
        "role": "system",
        "content": "Answer the following questions as best as you can. You have access to the following tools:",
        "tools": tools
    }

完整的对话代码如下:

import traceback
from transformers import AutoTokenizer, AutoModelForCausalLM
from tool_register import get_tools, dispatch_tool


modelPath = "/mnt/workspace/chatglm3-6b"


def chat(model, tokenizer, message, history, system):
    messages = []
    if system is not None:
        messages.append(system)

    if history is not None:
        for his in history:
            user, assistant = his
            messages.append({"role": "user", "content": user})
            messages.append({"role": "assistant", 'metadata': '', "content": assistant})

    print(messages)
    try:
        response = model.chat(tokenizer, message, messages, max_length=2048, top_p=0.9, temperature=0.45, repetition_penalty=1.1, do_sample=True)
        return response

    except Exception:
        traceback.print_exc()


def loadTokenizer():
    tokenizer = AutoTokenizer.from_pretrained(modelPath, use_fast=False, trust_remote_code=True)
    return tokenizer


def loadModel():
    model = AutoModelForCausalLM.from_pretrained(modelPath, device_map="auto", trust_remote_code=True).cuda()
    model = model.eval()
    # print(model)
    return model


def main():
    model = loadModel()
    tokenizer = loadTokenizer()

    # message2 =  '''
    # 时间线和流程进度:在面试过程中,面试者和HR可能会询问候选人投递、笔试、测评和两面等环节的时间节点,以及是否已经完成了一些面试 rounds。
    # 语言和成绩:面试官可能会询问候选人的英语六级和考研成绩,以评估其在学术上的能力。
    # 项目和代码:面试官可能会要求候选人描述其 previous project 中使用的技术栈,以及如何解决其中遇到的问题。他们还可能会要求演示代码,或者询问一些细节问题以检验候选人的技能和理解。
    # 请你告诉我面试中的面试问题有那些类型
    # '''
    message1 = '''
    请你根据下面的内容,总结以下面试时常见的面试问题类型: { "title": "阿里智能信息 流程中 持续更新", "content": "分享时间线,攒人品\n'Java研发 阿里系的感觉流程慢,HR和面试官忙不过来。\n'4.3 投递\n'4.12 笔试+测评\n'4.17 一面\n'4.26 二面\n'状态:面试中,不知道后面是三面还是HR面,有没有流程快的佬给讲一下\n'\n'\n'\n'\n'", "url": "https://www.nowcoder.com/feed/main/detail/e756838a61d1400f90c6d947b9c103f7" }, { "title": "阿里国际java二面凉经", "content": "1. 自我介绍\n'2. 问英语六级、考研成绩\n'3. 项目拷打\n' a. netty\n' b. 负责的模块说明\n'4. 八股\n' a. java基础\n' ⅰ. hashMap的数据结构\n' ⅱ. 讲到了扩容和缩容,追问扩容和缩容过程会发生什么\n' ⅲ. 引出ConcurrentHashMap,怎么保障线程安全,底层原理?\n' ⅳ. cas的底层原理\n' ⅴ. 进而追问cpu怎么和主存进行交互【其实想问Unsafe】\n' ⅵ. cas引出volatile关键字,底层实现【内存屏障】\n' ⅶ. sync的底层实现,monitor怎么依赖操作系统来实现的\n' ⅷ. 再串联CHL队列和AQS队列【真记不清了\n' b. redis\n' ⅰ. redis的内存结构部署和数据结构\n' ⅱ. redis的io模型,为什么要用这个reactor单线程模型\n' ⅲ. redis的持久化 \n' 1. 比对两种方法,\n' 2. 分别在什么场景使用\n' 3. 你怎么选取策略\n' 4. 具体怎么配置??【真不会\n' ⅳ. redis集群【真不会\n' c. mysql\n' ⅰ. innodb的事务隔离机制\n' 1. 怎么实现可重复读\n' 2. mvcc具体存的是什么\n' 3. 事务日志是什么\n' ⅱ. 你知道mysql有哪些日志吗?\n' ⅲ. 知道怎么配置主从吗?【真不会\n'真的被打烂了\U0001f979!!!!30mins,晚上看就被挂了,不过意料之中,实验室做的都是单体项目,分布式真接触不到,不过理论背的真不行", "url": "https://www.nowcoder.com/feed/main/detail/b9514346c7b445129886ea728d1e7857" }, { "title": "阿里国际 LAZADA一面凉经", "content": "4.07投递\n'4.15笔试\n'然后一直显示"面试安排中",但是没约面\n'4.28打电话问我愿不愿意转java(一开始投递C++研发工程师)\n'4.29一面,感觉是kpi面\n'电话面了30mins,问了计网和redis,还有拷打项目,没写代码\n'揪住细节往下问得很深,还会问具体应用情景,感觉不是背八股文能回答上来的,鼠鼠就只能一直说不太了解\n'感觉面试官全程无精打采,时不时还在叹气,鼠鼠全程汗流浃背\n'面完上官网查了下状态,果然秒挂", "url": "https://www.nowcoder.com/feed/main/detail/f62f5629edd44621a5c7759c9cac6f30" },
    '''
    history = []

    tools = get_tools()

    system = {
        "role": "system",
        "content": "Answer the following questions as best as you can. You have access to the following tools:",
        "tools": tools
    }

    response,_ = chat(model, tokenizer, message1, [], system)
    print('here\'s the result')
    print(response)
    message2 = f'''
    根据下面的内容,请你从中提炼出面试中会出现的问题类型
    {response}
    '''
    response,_ = chat(model, tokenizer, message2, [], system)
    print('here\'s the result')
    print(response)


if __name__ == "__main__":
    main()
  1. 我提供给大模型3个牛客网站的面试经验帖子,并要求它 请你根据下面的内容,总结以下面试时常见的面试问题类型

  2. 我获取大模型的response,将其作为第二次对话的 pompt传入,附上要求根据下面的内容,请你从中提炼出面试中会出现的问题类型
    请注意!!这个指示可以告诉大模型,使用我定义的function call工具,将原先文本化的答案转化为格式化的输出

结果

第一个结果:给出大模型根据面经博客总结的面试问题类型
第二个结果:大模型把自己刚刚的回答,转成了格式化的结果如下

{'name': 'get_interview_question_types', 'parameters': {'question_types': ['自我介绍', '技术问题', '项目经历', '英语水平', '面试官评估', '知识深入程度', '转行问题']}}

在这里插入图片描述

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值