本地部署,标准 HTTP 接口,任意语言均可调用
ZhiMeiAPI.exe --port 5000 --key ABCD-EFGH-IJKL-MNOP
| 参数 | 简写 | 必填 | 说明 |
|---|---|---|---|
--port | -p | 是 | 服务监听端口 |
--key | -k | 是 | 卡密 |
--nogpu | 无 | 否 | 加上表示禁用 GPU,仅用 CPU |
启动成功后,通过 http://<机器地址>:<port>/ 访问下面的接口。
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /api/status | 查询服务状态 |
| POST | /api/rewrite | 提交文本改写 |
| POST | /api/stop | 停止当前生成任务 |
| POST | /api/shutdown | 关闭程序 |
| POST | /api/license/logout | 退出登录(释放卡密授权占用,不关闭程序) |
| POST | /api/license/relogin | 重新登录(使用传入的卡密重新激活) |
/api/status
{
"isActivated": true,
"maxThread": 4,
"performanceScore": 87.5,
"isModelLoaded": true,
"unauthorizedReason": null
}
curl http://127.0.0.1:5000/api/status
import requests
print(requests.get("http://127.0.0.1:5000/api/status").json())
using var http = new HttpClient { BaseAddress = new Uri("http://127.0.0.1:5000") };
var status = await http.GetFromJsonAsync<StatusResponse>("api/status");
public record StatusResponse(bool IsActivated, int MaxThread, float PerformanceScore, bool IsModelLoaded, string? UnauthorizedReason);
/api/rewrite
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
content | string | 是 | 需要改写的原文 |
level | int | 否(默认 5) | 改写强度,1~10 |
stream | bool | 否(默认 false) | 是否流式返回 |
/api/status 返回的 maxThread 决定(根据显存/性能自动评估)。超出并发上限的请求会在服务端自动排队等待空闲槽位,无需客户端自行限流,但排队期间响应会相应延迟。
success 为 false、error 携带具体原因;不会返回部分结果或占位符内容,请直接根据 error 提示重试。
响应:
{ "success": true, "result": "改写后的内容", "error": null }
curl -X POST http://127.0.0.1:5000/api/rewrite \ -H "Content-Type: application/json" \ -d "{\"content\":\"这是一段需要改写的文字\",\"level\":5,\"stream\":false}"
import requests
resp = requests.post(
"http://127.0.0.1:5000/api/rewrite",
json={"content": "这是一段需要改写的文字", "level": 5, "stream": False},
timeout=300,
)
data = resp.json()
print(data["result"] if data["success"] else data["error"])
using var http = new HttpClient { BaseAddress = new Uri("http://127.0.0.1:5000"), Timeout = TimeSpan.FromMinutes(5) };
var response = await http.PostAsJsonAsync("api/rewrite", new { content = "这是一段需要改写的文字", level = 5, stream = false });
var result = await response.Content.ReadFromJsonAsync<RewriteResult>();
Console.WriteLine(result!.Success ? result.Result : result.Error);
public record RewriteResult(bool Success, string Result, string? Error);
响应为 SSE,每段以 data: <内容>\n\n 推送,结束时发送 data: [DONE]\n\n。
curl -N -X POST http://127.0.0.1:5000/api/rewrite \ -H "Content-Type: application/json" \ -d "{\"content\":\"这是一段需要改写的文字\",\"level\":5,\"stream\":true}"
import requests
resp = requests.post(
"http://127.0.0.1:5000/api/rewrite",
json={"content": "这是一段需要改写的文字", "level": 5, "stream": True},
stream=True,
timeout=300,
)
for line in resp.iter_lines(decode_unicode=True):
if not line or not line.startswith("data: "):
continue
payload = line[len("data: "):]
if payload == "[DONE]":
break
print(payload, end="", flush=True)
using var http = new HttpClient { BaseAddress = new Uri("http://127.0.0.1:5000") };
var request = new HttpRequestMessage(HttpMethod.Post, "api/rewrite")
{
Content = JsonContent.Create(new { content = "这是一段需要改写的文字", level = 5, stream = true })
};
using var response = await http.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);
await using var stream = await response.Content.ReadAsStreamAsync();
using var reader = new StreamReader(stream);
string? line;
while ((line = await reader.ReadLineAsync()) is not null)
{
if (!line.StartsWith("data: ")) continue;
var payload = line["data: ".Length..];
if (payload == "[DONE]") break;
Console.Write(payload);
}
| 状态码 | 说明 |
|---|---|
| 403 | 服务未授权 |
| 400 | content 为空或 level 不在 1~10 |
| 499 | 客户端主动断开连接 |
| 504 | 改写超时 |
| 500 | 内部异常 |
/api/stop
curl -X POST http://127.0.0.1:5000/api/stop
import requests
print(requests.post("http://127.0.0.1:5000/api/stop").json())
var resp = await http.PostAsync("api/stop", null);
Console.WriteLine(await resp.Content.ReadAsStringAsync());
/api/shutdown
curl -X POST http://127.0.0.1:5000/api/shutdown
import requests
print(requests.post("http://127.0.0.1:5000/api/shutdown").json())
var resp = await http.PostAsync("api/shutdown", null);
Console.WriteLine(await resp.Content.ReadAsStringAsync());
/api/license/logout
仅释放当前卡密占用的授权 Session(例如准备更换设备时使用),不会关闭程序。调用成功后本进程会转为未授权状态,/api/rewrite 会返回 403,直到重新调用 /api/license/relogin 或程序重新自动激活成功。
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
key | string | 是 | 需要释放授权占用的卡密 |
{ "message": "退出登录成功,已释放授权占用" }
curl -X POST http://127.0.0.1:5000/api/license/logout \ -H "Content-Type: application/json" \ -d "{\"key\":\"ABCD-EFGH-IJKL-MNOP\"}"
import requests
resp = requests.post("http://127.0.0.1:5000/api/license/logout", json={"key": "ABCD-EFGH-IJKL-MNOP"})
print(resp.json())
var resp = await http.PostAsJsonAsync("api/license/logout", new { key = "ABCD-EFGH-IJKL-MNOP" });
Console.WriteLine(await resp.Content.ReadAsStringAsync());
/api/license/relogin
使用传入的卡密重新调用授权服务器激活。可以是当前卡密(重新激活/续期失败后手动恢复),也可以是另一个卡密(切换授权)。激活成功后该卡密会成为程序当前生效的卡密,后续自动续租、退出登录都会使用它。
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
key | string | 是 | 用于重新登录的卡密 |
{ "message": "重新登录成功" }
失败时 message 会携带具体原因,例如:
{ "message": "重新登录失败: 该卡密正在被其他客户端使用" }
curl -X POST http://127.0.0.1:5000/api/license/relogin \ -H "Content-Type: application/json" \ -d "{\"key\":\"ABCD-EFGH-IJKL-MNOP\"}"
import requests
resp = requests.post("http://127.0.0.1:5000/api/license/relogin", json={"key": "ABCD-EFGH-IJKL-MNOP"})
print(resp.json())
var resp = await http.PostAsJsonAsync("api/license/relogin", new { key = "ABCD-EFGH-IJKL-MNOP" });
Console.WriteLine(await resp.Content.ReadAsStringAsync());