docs/cn/run/cli/local-server.mdx
import Feedback from "/snippets/page-feedback.mdx";
GenieX 内置推理服务器,提供兼容 OpenAI 协议的 API。在设备端运行模型,并连接到任意支持 OpenAI 协议的应用或框架——例如 LangChain 等智能体框架、OpenClaw 等 AI 原生应用,或你自己的代码。无需云端依赖。
拉取模型:
geniex pull ai-hub-models/Qwen3-4B-Instruct-2507
启动服务器:
geniex serve
服务器默认运行在 http://127.0.0.1:18181。保持该终端开启,并在另一个终端中发送请求。运行 geniex serve -h 查看所有可配置选项。
为给定对话创建模型响应。支持 LLM(纯文本)与 VLM(图像 + 文本)。
{
"model": "ai-hub-models/Qwen3-4B-Instruct-2507",
"messages": [
{"role": "user", "content": "Hello! Briefly introduce yourself."}
],
"max_tokens": 256,
"temperature": 0.7,
"stream": false
}
在浏览器中打开 http://127.0.0.1:18181 即可访问内置的 Swagger UI。
步骤 1. 展开 POST /v1/chat/completions 端点,查看示例请求体与 schema。
步骤 2. 点击 Try it out,根据需要编辑请求体,然后点击 Execute。
步骤 3. 查看响应——200 状态码以及模型生成的回复。
image_url.url 支持三种格式:
| 格式 | 示例 |
|---|---|
本地文件路径(file:// 前缀可选) | C:/Users/Username/Pictures/photo.jpg、file:///tmp/photo.jpg |
| HTTP / HTTPS URL——由服务器拉取 | https://example.com/image.jpg |
| Base64 data URL——内联图像字节 | data:image/png;base64,iVBORw0KGgo... |
{
"model": "ai-hub-models/Qwen2.5-VL-7B-Instruct",
"messages": [
{
"role": "user",
"content": [
{"type": "text", "text": "Describe this image succinctly."},
{"type": "image_url", "image_url": {"url": "</path/to/image>"}}
]
}
]
}
在 Swagger UI 中将请求体替换为上述 VLM payload,把 image_url.url 指向本地图片,然后点击 Execute。
由于服务器使用 OpenAI 协议,可直接将官方 openai Python 客户端指向本地端点,复用任意已有的 OpenAI 代码。先通过 pip install openai 安装,然后创建 client:
from openai import OpenAI
client = OpenAI(
base_url="http://127.0.0.1:18181/v1",
api_key="geniex", # any non-empty string; the server does not check it
)
下面的示例都复用此 client。请把 model 替换为已拉取的模型;可选的 :<precision> 后缀(例如 Q4_0、Q4_K_M、Q8_0)选择量化变体——Q4_0 推荐用于 Hexagon NPU 上的 llama.cpp。详见支持的精度(量化)。
按 delta 到达顺序逐段打印:
stream = client.chat.completions.create(
model="unsloth/Qwen3-4B-GGUF:Q4_0",
messages=[
{"role": "user", "content": "Hello! Briefly introduce yourself."},
],
max_tokens=256,
temperature=0.7,
stream=True,
)
for chunk in stream:
delta = chunk.choices[0].delta.content
if delta:
print(delta, end="", flush=True)
print()
单次请求、单次响应,不启用流式——标准的 OpenAI chat.completions.create 形式。enable_think=False 关闭 Qwen3 默认的 <think>…</think> 推理前缀,让回复内容更干净。
resp = client.chat.completions.create(
model="unsloth/Qwen3-4B-GGUF:Q4_0",
messages=[
{"role": "user", "content": "Hello! Briefly introduce yourself."},
],
max_tokens=128,
temperature=0.7,
extra_body={"enable_think": False},
)
print(resp.choices[0].message.content)
print("finish_reason:", resp.choices[0].finish_reason)
print("usage:", resp.usage)
输出:
Hello! I'm Qwen, a large language model developed by Alibaba Cloud. I can help with a wide range of tasks, including answering questions, writing articles, creating stories, and more. I'm here to assist you in any way I can! How can I help you today?
finish_reason: stop
usage: CompletionUsage(completion_tokens=58, prompt_tokens=19, total_tokens=77, ...)
函数/工具调用使用标准的 OpenAI tools schema。服务器会从模型生成的文本中解析工具调用(<tool_call>…</tool_call> 标签或 ```json 代码块——例如 Qwen3 的 chat template 产出的格式),并以 OpenAI tool_calls 形式返回。
两步往返:(1) 模型返回一条 tool_calls 消息;(2) 本地执行工具,将结果作为 role="tool" 消息回传给模型,模型基于结果生成最终答案。
import json
tools = [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get the current weather in a given city.",
"parameters": {
"type": "object",
"properties": {
"city": {"type": "string", "description": "City name, e.g. Beijing"},
},
"required": ["city"],
},
},
}
]
def get_weather(city: str) -> dict:
# replace this with your real implementation
return {"city": city, "temperature_c": 24, "condition": "Sunny"}
messages = [
{"role": "user", "content": "What is the weather in Beijing? Use the tool."},
]
# Step 1 — model requests a tool call.
first = client.chat.completions.create(
model="unsloth/Qwen3-4B-GGUF:Q4_0",
messages=messages,
tools=tools,
tool_choice="auto",
max_tokens=256,
extra_body={"enable_think": False},
)
call = first.choices[0].message.tool_calls[0]
print("finish_reason:", first.choices[0].finish_reason) # -> "tool_calls"
print("call:", call.function.name, call.function.arguments)
# Step 2 — run the tool, feed the result back.
result = get_weather(**json.loads(call.function.arguments))
messages.append(first.choices[0].message)
messages.append(
{
"role": "tool",
"tool_call_id": call.id,
"content": json.dumps(result),
}
)
final = client.chat.completions.create(
model="unsloth/Qwen3-4B-GGUF:Q4_0",
messages=messages,
tools=tools,
max_tokens=128,
extra_body={"enable_think": False},
)
print(final.choices[0].message.content)
输出:
finish_reason: tool_calls
call: get_weather {"city": "Beijing"}
The weather in Beijing is 24°C and sunny.
GET /v1/models——列出可用模型。GET /v1/models/{model}——查询指定模型的信息。