[ggerganov/llama.cpp]添加对oai python服务器中函数调用的基本支持

2024-07-05 965 views
6

我想尝试使用 oai python 服务器来运行magentic。要正常工作,需要实现用于函数调用的 oai api。

函数调用允许 LLM 使用函数调用而不是仅使用文本消息进行响应。会自动生成语法,通过提供的函数 json 方案来约束 LLM 响应。当客户端回复函数结果时,它们将包含在聊天提示中。

磁性用法示例:

> server -m open-llama-7b-v2-q8_0.gguf # or some other model
> python api_like_OAI.py --chat-prompt "" --stop "USER:"
import openai
from magentic import prompt
from magentic import prompt_chain
from pydantic import BaseModel
from enum import Enum

# connect to api_like_OAI.py 
openai.api_base = "http://127.0.0.1:8081"
openai.api_key = ""

@prompt('Add more "dude"ness to: {phrase}')
def dudeify(phrase: str) -> str:
    ...  # No function body as this is never executed

print(dudeify("Hello, how are you?"))
# " Dude. How're ya doin', brotha? [insert random gibberish]..."

class Element(str, Enum):
    fire = 'fire'
    water = 'water'
    plant = 'plant'
    stone = 'stone'
    air = 'air'

class Superhero(BaseModel):
    hero_name: str
    age: int
    element: Element
    power: str
    enemies: list[str]

class SuperheroTeam(BaseModel):
    team_name: str
    members: list[Superhero]

@prompt("You create named superheros.\n\nA Superhero named {example_name}: {example}\nA Superhero named {name}:")
def create_superhero(name: str, example_name:str, example:str) -> Superhero:
    ...

@prompt("You create named superhero teams. Give each hero a name.\n\n" + 
         "Superhero team named {example_name}: {example}\nSuperhero team named {name}: ")
def create_superhero_team(name: str, example_name:str, example:str) -> SuperheroTeam:
    ...

superhero = Superhero(hero_name='Garden Man', age=30, power='Control over plants',
                      element=Element.plant, enemies=['Pollution Man', 'Concrete Woman'])

new_hero = create_superhero("Tree Mage", example_name=superhero.hero_name, example=superhero.model_dump_json())
print(new_hero)

team = SuperheroTeam(team_name="The Leafs", members=[superhero, new_hero])
new_team = create_superhero_team("Mountain Guard", example_name=team.team_name, example=team.model_dump_json())

print(team)
print(new_team)
# hero_name='Tree Mage' age=25 element=<Element.plant: 'plant'> power='control trees' enemies=['Garden Man', 'Humidity Girl']
# team_name='The Leafs' members=[
#  Superhero(hero_name='Garden Man', age=30, element=<Element.plant: 'plant'>, power='Control over plants', enemies=['Pollution Man', 'Concrete Woman']), 
#  Superhero(hero_name='Tree Mage', age=25, element=<Element.plant: 'plant'>, power='control trees', enemies=['Garden Man', 'Humidity Girl'])]
# team_name='Mountain Guard' members=[
#  Superhero(hero_name='Bear Biker', age=23, element=<Element.fire: 'fire'>, power='burning fire to turn into bike and attack', enemies=['Fireman', 'Flame Maiden']),
#  Superhero(hero_name='Cactus Climber', age=34, element=<Element.plant: 'plant'>, power='hanging from the top of a tree with cacti as climbing aids. Can use them for melee attacks or even to fire projectiles from her spines.', enemies=['Fireman'])]

回答

0

为什么这个 PR 包含注释掉的代码?

9

好问题,现在删除了。

5

@ejones 啊,谢谢你指出了json-schema-to-grammar.py,我完全忽略了它!我会考虑利用这一点。我想我会在没有属性排序的情况下使用它,这样用户就可以仅通过 json 中的顺序来指定属性的顺序。

9

是的,我的意思是,鉴于它是一个 OAI 兼容层,我认为没有地方将属性顺序作为参数。

值得一提的是,在 中json-schema-to-grammar.py,prop order 是为了解决对象属性应该以什么顺序呈现给模型的问题。这可能会影响生成,因为它决定了模型首先提交对象的哪些值。由于 JSON / JSON 模式通常将对象属性视为无序的,因此这可能与源顺序不同。但是,同样,由于这是作为 OAI 的替代品,我不确定是否有其他选择。

6

prop order 是为了解决对象属性应该以什么顺序呈现给模型的问题

尽管 json 模式表明它是无序的,但 json 转换器的工作方式是按字母顺序重新排列未指定的属性。对于生成的 json 模式,它们是按照属性出现的顺序生成的,因此如果它可以对模式属性有一个默认的“迭代顺序”而不是选择字母顺序,那么您会更容易使用默认值。