
兄弟们,我又来了。前两天发了个帖子《 MCP 到底是个什么鬼?》,没想到对大家有点小帮助,非常开心。
用 LLM 的时候,工具调用确实是一个很烦的事情(它不难,就是很繁琐),要么你在某个框架里面,把你的工具封装成 MCP 服务,要么你在某个框架里面用它的机制包装(比如加一个装饰器 @tool ),五花八门。
有没有简单一点的办法呢?有的,比如最近的 lang 家的 deepagents 里面的方式就已经接近优雅了,它可以让你直接使用自己写的函数,函数(工具)本身你想怎么写怎么写,但是,他又搞了个 middleware 的 tool ,看着又很反直觉了,又得学怎么搞,本来挺清爽的,又搞复杂了。
好麻烦,不就是给 LLM 传工具么?为什么来来回回搞得这么复杂呢?有必要么?
于是,我前两天更新了一下我的库 :chak ( https://github.com/zhixiangxue/chak-ai ),就干一件事情:让你自己写的函数、对象,都能传给 LLM ,让它当工具用,而你不需要写任何额外的东西,连 @tool 这样的装饰器都不需要,就像这样:
# 这个函数你该怎么写就怎么写,不需要很麻烦的封装成什么 MCP Server ,不需要加装饰器,不需要任何植入 def get_weather(city: str) -> str: """查询城市天气""" return requests.get(f'xxxx.com?city={city}').text cOnv= chak.Conversation("openai/gpt-4o", tools=[get_weather]) # 直接把函数传进来就行了 respOnse= conv.send("北京天气怎么样?") 或者这样:
from pydantic import BaseModel, Field class UserInput(BaseModel): name: str = Field(description="User's full name") email: str = Field(description="User's email address") age: int = Field(description="User's age") class UserOutput(BaseModel): id: int name: str status: str = "active" # 你的工具的输入输出只要是可以序列化的就行,不必是简单类型,也不需要装饰任何东西 def create_user(user: UserInput) -> UserOutput: """Create a new user""" return UserOutput(id=123, name=user.name, status="active") cOnv= chak.Conversation( "openai/gpt-4o", tools=[create_user] # 直接传进来 ) respOnse= await conv.asend("Create a user: John Doe, [email protected], 30 years old") 如果你喜欢把工具封装到一个类里面(这很常见对吧),你传给 LLM 一个对象也是可以的,Chak 会帮你保持对象的状态,调用完成后,你的对象甚至是带有状态更新的,相当于你可以喂给 LLM 一个你的工作流,而这个工作流就是一个普通的对象,像这样:
# 定义一个购物车 class ShoppingCart: def __init__(self): self.items = [] self.discount = 0 def add_item(self, name: str, price: float, quantity: int = 1): """Add item to cart""" self.items.append({"name": name, "price": price, "quantity": quantity}) def apply_discount(self, percent: float): """Apply discount percentage""" self.discount = percent def get_total(self) -> float: """Calculate total price""" subtotal = sum(item["price"] * item["quantity"] for item in self.items) return subtotal * (1 - self.discount / 100) cart = ShoppingCart() cOnv= chak.Conversation( "openai/gpt-4o", tools=[cart] # 直接把这个对象作为工具 ) # 让 LLM 帮你在这个购物车里面做一些操作 respOnse= await conv.asend( "Add 2 iPhones at $999 each, then apply 10% discount and tell me the total" ) # LLM 折腾完了之后,你的购物车里面的数据就更新了,你都不需要解析什么 LLM 的输入(因为很多时候 LLM 输出的 Json 未必准确,有各种乌七八糟的问题),chak 自动帮你把这事情干完了 print(cart.items) # [{'name': 'iPhone', 'price': 999, 'quantity': 2}] print(cart.discount) # 10 print(cart.get_total()) # 1798.2 所以,“工具调用非得用 MCP 、学 MCP 吗?” 其实大可不必(当然 Chak 也是支持 MCP 的,用起来也非常简单)
让 LLM 可以调用工具,就应该这么简单才丝滑,对吧...
工具调用本应该是助力 LLM 变得更强的,现在很多时候成了开发者的负担。如果你也烦透了这事,真心可以试试 chak:它把这些破事都打包了,你只管写业务代码,非常轻量级,依赖非常少。
项目地址: https://github.com/zhixiangxue/chak-ai
各位帮忙使用一下,好用的话帮我点个啊,随时提 bug 、issue ,感谢~