local-llm-function-calling
让本地大模型支持函数调用,词表级 JSON Schema 约束确保输出格式绝对合规
加载项目详情…
本应用为开源项目,仅供学习研究,请遵守其开源协议。
让本地大模型支持函数调用,词表级 JSON Schema 约束确保输出格式绝对合规
加载项目详情…
本应用为开源项目,仅供学习研究,请遵守其开源协议。
当你让 GPT-4 帮你查天气时,它能正确调用工具函数并返回格式化结果——这是 OpenAI 在 2023 年中推出的 Function Calling 功能,是大模型从聊天玩具走向实用工具的关键一跃。但 OpenAI 的模型是闭源云端运行的,不仅调用有成本,私有数据也得交给第三方。 那么问题来了:本地部署的开源模型(如 Llama、Hugging Face 上的各种模型)能不能也支持函数调用? 这就是 local-llm-function-calling 做的事情。作者 rizerphe 用纯 Python 构建了一套框架,让 Hugging Face 生态下的文本生成模型能够严格遵循 JSON Schema 输出,从而可靠地调用工具函数。相比 OpenAI 的实现,这套方案的优势在于:真正强制约束输出格式(OpenAI 只是推荐,而该项目通过 token 级约束真正做到了),完全本地运行,数据不外泄。
大多数函数调用方案依赖 Prompt Engineering——通过精心设计的提示词哄劝模型输出正确格式。但这种方法在小模型上表现不稳定,容易出现 JSON 语法错误、字段缺失、格式混乱等问题。 local-llm-function-calling 采用了更底层的方法:词表约束(Token Constraint)。库中的核心组件 Constrainer 在每个生成步(token-by-token)都会检查当前已生成的文本是否符合 JSON Schema 的约束规则:
from local_llm_function_calling import Constrainer, JsonSchemaConstraint
from local_llm_function_calling.model.huggingface import HuggingfaceModel
# 定义 JSON Schema 约束
schema_constraint = JsonSchemaConstraint(schema)
constrainer = Constrainer(HuggingfaceModel('gpt2'))
# 在约束下生成:模型只能在符合 schema 的 token 中选择
generated = constrainer.generate('...', schema_constraint)
这背后的实现依赖 json-schema-enforcer 库——同样是作者自研的项目——它在每个生成步对整个词表做过滤,只保留那些加上之后仍能最终形成合法 JSON 的有效 token。这一步的工程实现相当精妙:在 transformers 的 logits 输出层面做剪枝,不改变模型本身,不引入额外采样开销。
项目的代码架构非常清晰,分为三层: 第一层:模型抽象(model/)。目前支持两种模型后端:HuggingfaceModel(基于 transformers)和 LogitLlama(基于 llama.cpp)。每种模型都实现统一的 Model 协议,提供 start_generation() 方法启动逐 token 生成流程,并返回实现 Generation 协议的对象。 第二层:提示器抽象(prompter.py)。提示器负责把用户输入和函数定义转换为模型能理解的文本序列。项目内置了 CompletionModelPrompter(适合 GPT-2 风格的 Completion 模型)和 InstructModelPrompter(适合指令微调模型),并为 CodeLlama 微调版提供了专用的 CodeLlamaFunctionCallingPrompter。 第三层:约束器(constrainer.py)。Constrainer 是连接模型与约束的核心编排类,它迭代调用模型的生成接口,同时在每步用约束器验证当前输出是否仍然合法。对于函数调用场景,项目还提供了专用的 Generator 类,封装了两阶段流程:先决定调用哪个函数,再生成函数参数。
该库的核心价值在于让本地模型可靠地输出结构化数据,典型的应用场景包括: 信息抽取:给定一段非结构化文本,让模型从中提取实体、关系等结构化信息,结果直接是合规的 JSON。 API 调用链:在 Agent 架构中,本地模型通过 Function Calling 调用外部工具,每次调用的参数都是合法 JSON。 对话状态管理:将对话状态用 JSON Schema 约束,确保多轮对话中的状态更新不会产生格式错误。 由于完全运行在本地,这类场景特别适合对数据隐私有严格要求的行业(如医疗、金融、法律)的 AI 应用开发。
安装本身非常简单:
pip install local-llm-function-calling
如需 llama.cpp 后端(支持量化模型,降低显存要求):
pip install local-llm-function-calling[llama-cpp]
不过需要注意的是,尽管 gpt2 这种小模型可以在 CPU 上运行,但实际有意义的函数调用场景通常需要 6B 参数以上的模型,这意味着 GPU 是必需的。项目对显存的要求取决于模型大小——7B 量化模型(Q4_K_M)大约需要 6GB VRAM,13B 模型需要 10GB 以上。 项目没有提供 Docker 支持,也没有 Web UI,定位是供开发者集成的 Python 库而非独立部署的工具。如果你需要图形界面或 Docker 部署,需要自行包装。
约束速度开销:词表约束在每步生成时都要遍历并过滤整个词表(通常 5 万+ token),对大词表模型会有明显的延迟增加。作者在 README 中也提到了这一点,并建议对延迟敏感的场景做预过滤优化。 中文支持有限:项目默认基于英文的 tokenizer 和 JSON Schema,对中文内容的约束效果可能不如英文场景稳定。 模型依赖性:不同模型对约束的服从度差异很大,经过指令微调或专门为函数调用训练的模型(如 Meta 的 CodeLlama Instruct)效果显著优于基础模型。
local-llm-function-calling 是本地大模型工具调用领域一个实用且工程实现有深度的项目。它将 OpenAI 的 Function Calling 能力以纯本地、无依赖闭源模型的方式复现,通过词表级约束而非纯提示工程来实现格式控制,架构清晰、易于扩展。对于需要在本地部署 AI 应用、对数据隐私有要求、或希望基于开源模型构建 Agent 系统的开发者,这是一个值得关注和试用的工具。 项目链接:https://github.com/rizerphe/local-llm-function-calling 文档地址:https://local-llm-function-calling.readthedocs.io/