如何把 tinygrad LLM 服务的 OpenAI 兼容 API 接入聊天机器人并解析 tool call
【免费下载链接】tinygradYou like pytorch? You like micrograd? You love tinygrad! ❤️项目地址: https://gitcode.com/GitHub_Trending/tiny/tinygrad
tinygrad 自带一个 LLM 服务:用--serve启动后,它在/v1路径下提供 OpenAI 兼容 API(tinygrad/llm/serve.py)。你的聊天机器人代码不需要为 tinygrad 写专用客户端,直接用 OpenAI SDK 并把base_url指向这个服务即可;服务端负责渲染聊天模板、把模型输出中的 tool call 块解析并转换成 OpenAI 格式的tool_calls,你的机器人拿到后执行本地工具、再把结果回传,完成多轮工具循环。本文覆盖:启动服务、验证连通性、用 OpenAI SDK 发起流式/非流式请求、声明工具并解析tool_calls、以及回传工具结果的完整闭环。
准备条件
- 已安装 tinygrad 的 Python 环境。
- 已安装
jinja2:服务会优先使用 GGUF 模型自带的 chat template(jinja2.Environment加载 tokenizer.chat_template),这是工具调用依赖的模板;未安装 jinja2 时服务端打印warning: jinja2 is not installed, the model's chat template is disabled,并回退到FallbackTemplate,该模板明确不支持 tool calling。 - 已安装
openai包(客户端侧)。test/null/test_llm_server.py 的集成测试就是直接from openai import OpenAI打这个服务。 - 一个 GGUF 模型:内置模型名(
llama3.2:1b、llama3.2:3b、qwen3:0.6b等,见 tinygrad/llm/cli.py 中的models字典),或本地 GGUF 文件路径。
启动 OpenAI 兼容服务
python3 -m tinygrad.llm --serve 8123 --model qwen3:0.6b参数说明(见 cli.py):
--serve [PORT]:启动 OpenAI 兼容 API;带参数时为该端口,不带参数(只写--serve)默认 8000。--model / -m:内置模型名或本地 GGUF 文件路径,默认取models字典第一个键(llama3.2:1b)。--max_context:最大上下文长度,默认 4096。--no_chat_template:跳过模型自带模板、强制使用 fallback 模板;需要工具调用时不要加。
服务启动时会打印使用的模型名、字节数、参数量与最大上下文,并执行 JIT 预热(serve 模式默认 warmup)。用浏览器直接访问http://localhost:8123会返回内置聊天页 chat.html,可以随手确认服务活着。
验证连通性:GET /v1/models
服务实现的端点有GET /v1/models和POST /v1/chat/completions,其他路径不处理(serve.py)。用curl做一次冒烟检查:
curl http://localhost:8123/v1/models按 测试用例 的口径判断成功:状态码 200,响应 JSON 中object为"list",data[0]["object"]为"model",data[0]["id"]是本服务加载模型的名称。
接入 OpenAI 客户端
客户端只需把base_url指向服务的/v1,api_key服务端不校验,测试中传的字符串是"test"(test_llm_server.py):
from openai import OpenAI client = OpenAI(base_url="http://localhost:8123/v1", api_key="test")非流式请求
resp = client.chat.completions.create( model="qwen3:0.6b", # 用 /v1/models 返回的 id messages=[ {"role": "system", "content": "You are helpful."}, {"role": "user", "content": "Hello"}, {"role": "assistant", "content": "Hi!"}, {"role": "user", "content": "How are you?"}, ], stream=False, ) print(resp.object, resp.choices[0].finish_reason)按 测试 的口径:resp.id以chatcmpl-开头,resp.object为"chat.completion",choices[0].message.role为"assistant",finish_reason为"stop",usage含prompt_tokens/completion_tokens。
流式请求
stream = client.chat.completions.create( model="qwen3:0.6b", messages=[{"role": "user", "content": "Hello"}], stream=True, stream_options={"include_usage": True}, ) for chunk in stream: if chunk.choices: delta = chunk.choices[0].delta if delta.content: print(delta.content, end="") if chunk.usage: print("\n", chunk.usage)流式响应按 OpenAI 的chat.completion.chunk下发:首个 chunk 的delta.role为"assistant",最后一个带finish_reason(test)。stream_options={"include_usage": True}时,末尾会多一个choices为空、带usage的 chunk(服务端仅在stream_options.include_usage为真或请求非流式时附带 usage,见 serve.py)。
正文按delta.content分片;如果模型输出以think块开头,块内文本会走delta.reasoning_content字段(StreamRouter),正文与推理内容可以分开渲染。
声明工具并解析 tool call
服务端如何解析 tool call
请求体里带tools字段时,服务会把它交给 chat template 渲染(serve.py)。模型输出里的工具调用块由 parse_tool_call 解析,支持两种格式:
- JSON 格式(hermes 风格):
{"name": ..., "arguments": {...}},arguments缺失时会读parameters字段; - XML 格式:
<function=name><parameter=key>value</parameter>...</function>,参数值以合法 JSON 开头时按 JSON 解析,否则保留为字符串。
流式输出中,`
【免费下载链接】tinygradYou like pytorch? You like micrograd? You love tinygrad! ❤️项目地址: https://gitcode.com/GitHub_Trending/tiny/tinygrad
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考