用 Go 快速搭建一个 Coze (扣子) API 流式回复模拟接口(Mock Server)
在开发 Coze Bot 相关的前端功能时,我们经常需要测试流式回复(SSE)的打字机效果、加载状态、停止响应、内容渲染等逻辑。但直接调用真实的 Coze API 会消耗 token,而且回复速度和内容不可控。
下面分享一个纯 Go 实现的本地模拟接口 ,只需几分钟就能跑起来,完全兼容 Coze 的 /v3/chat 流式返回格式,让你零成本、无限次地测试前端体验。
功能亮点
- 完美还原 Coze 的 SSE 流式结构(
event: conversation.message.delta+data: {"content":"..."}) - 逐字打字机效果,延迟随机 50~150ms,模拟真人输入
- 支持 CORS,前端直接调用无需额外配置
- 回复内容支持 Markdown,前端可直接渲染
- 自动发送
[DONE]结束标志 - 代码简洁,只有不到 100 行
完整代码(mock_coze.go)
go
package main
import (
"fmt"
"io"
"log"
"net/http"
"strings"
"time"
)
const proxyPort = ":8680"
func main() {
http.HandleFunc("/coze-chat", mockHandler)
log.Printf("[MOCK] 模拟 Coze 接口已启动")
log.Printf("[MOCK] 监听地址: http://localhost%s/coze-chat", proxyPort)
log.Printf("[MOCK] 可直接用你原来的前端代码测试(无需 token)")
log.Fatal(http.ListenAndServe(proxyPort, nil))
}
func mockHandler(w http.ResponseWriter, r *http.Request) {
clientIP := r.RemoteAddr
log.Printf("[MOCK REQUEST] %s %s from %s", r.Method, r.URL.Path, clientIP)
// 处理 CORS 预检
if r.Method == http.MethodOptions {
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS")
w.Header().Set("Access-Control-Allow-Headers", "Content-Type")
w.Header().Set("Access-Control-Max-Age", "86400")
w.WriteHeader(http.StatusNoContent)
return
}
if r.Method != http.MethodPost {
http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed)
return
}
// 读取请求体(仅模拟,可忽略内容)
_, _ = io.ReadAll(r.Body)
defer r.Body.Close()
// 设置 SSE 响应头
w.Header().Set("Content-Type", "text/event-stream")
w.Header().Set("Cache-Control", "no-cache")
w.Header().Set("Connection", "keep-alive")
w.Header().Set("Access-Control-Allow-Origin", "*")
w.(http.Flusher).Flush()
// 自定义回复内容(支持 Markdown,随时修改)
fullResponse := `# 时尚审美评估师
**评判结果**:好看
**理由**:
- 这件帽衫的深灰色非常百搭,经典不过时,适合各种肤色。
- 版型宽松舒适,oversize 设计很有街头感,显瘦又时髦。
- 帽绳和袖口细节处理精致,质感看起来很不错(棉感强,不廉价)。
- 前胸的小logo绣标低调有质感,不会太张扬。
- 整体风格偏休闲运动风,日常穿搭、约会、逛街都非常合适。
**搭配建议**:
- 下装:黑色或深蓝牛仔裤 + 白球鞋(经典安全)
- 进阶:卡其色工装裤 + 马丁靴(更有层次)
- 外搭:短款羽绒服或风衣(冬天显高)
总体来说,这件帽衫设计简洁大方,性价比应该很高,值得入手!✨`
// 逐字输出,模拟打字机效果
for _, char := range fullResponse {
fmt.Fprintf(w, "event: conversation.message.delta\n")
fmt.Fprintf(w, "data: {\"id\":\"mock123\",\"conversation_id\":\"mock\",\"bot_id\":\"mock\",\"role\":\"assistant\",\"type\":\"answer\",\"content\":\"%s\",\"content_type\":\"text\"}\n\n", escapeJSON(string(char)))
w.(http.Flusher).Flush()
// 随机延迟,模拟人类打字速度
time.Sleep(time.Millisecond * time.Duration(50+(char%100)))
}
// 发送结束标志
fmt.Fprint(w, "event: done\ndata: [DONE]\n\n")
w.(http.Flusher).Flush()
log.Printf("[MOCK SUCCESS] 模拟回复完成,共输出 %d 个字符", len(fullResponse))
}
// 简单 JSON 转义函数
func escapeJSON(s string) string {
s = strings.ReplaceAll(s, "\\", "\\\\")
s = strings.ReplaceAll(s, "\"", "\\\"")
s = strings.ReplaceAll(s, "\n", "\\n")
s = strings.ReplaceAll(s, "\r", "\\r")
return s
}
使用方法
- 保存为
mock_coze.go - 运行:
bash
go run mock_coze.go
- 前端保持原有调用方式(URL 指向
http://localhost:8680/coze-chat即可)
自定义回复内容
只需修改 fullResponse 变量中的文本,支持任意 Markdown 格式。例如想测试负面评价:
go
fullResponse := "这件帽衫不太行,颜色暗沉、版型臃肿,建议再看看其他款~"
或者测试超长回复、代码块、列表等,都可以随意发挥。
总结
这个小工具极大提升了前端开发效率:
- 零成本、无限测试
- 完全还原真实流式体验
- 内容、速度可控
- 支持前后端联调
推荐所有在做 Coze Bot 前端交互的同学都备一个,调试 UI、加载状态、打字动画时简直无敌好用!