慢就是快 發表於 2025-12-18 09:06:06

Go语言快速搭建一个API流式回复本地模拟接口

<div id="navCategory"><h5 class="catalogue">目录</h5><ul class="first_class_ul"><li><a href="#_label0">功能亮点</a></li><li><a href="#_label1">完整代码(mock_coze.go)</a></li><li><a href="#_label2">使用方法</a></li><li><a href="#_label3">自定义回复内容</a></li><li><a href="#_label4">总结</a></li></ul></div><p>在开发 Coze Bot 相关的前端功能时,我们经常需要测试流式回复(SSE)的打字机效果、加载状态、停止响应、内容渲染等逻辑。但直接调用真实的 Coze API 会消耗 token,而且回复速度和内容不可控。</p>
<p>下面分享一个<strong>纯 Go 实现的本地模拟接口</strong>,只需几分钟就能跑起来,完全兼容 Coze 的 <code>/v3/chat</code> 流式返回格式,让你零成本、无限次地测试前端体验。</p>
<p class="maodian"><a name="_label0"></a></p><h2>功能亮点</h2>
<ul><li>完美还原 Coze 的 SSE 流式结构(<code>event: conversation.message.delta</code> + <code>data: {&quot;content&quot;:&quot;...&quot;}</code>)</li><li>逐字打字机效果,延迟随机 50~150ms,模拟真人输入</li><li>支持 CORS,前端直接调用无需额外配置</li><li>回复内容支持 Markdown,前端可直接渲染</li><li>自动发送 <code></code> 结束标志</li><li>代码简洁,只有不到 100 行</li></ul>
<p class="maodian"><a name="_label1"></a></p><h2>完整代码(mock_coze.go)</h2>
<div class="jb51code"><pre class="brush:go;">package main

import (
        "fmt"
        "io"
        "log"
        "net/http"
        "strings"
        "time"
)

const proxyPort = ":8680"

func main() {
        http.HandleFunc("/coze-chat", mockHandler)

        log.Printf(" 模拟 Coze 接口已启动")
        log.Printf(" 监听地址: http://localhost%s/coze-chat", proxyPort)
        log.Printf(" 可直接用你原来的前端代码测试(无需 token)")
        log.Fatal(http.ListenAndServe(proxyPort, nil))
}

func mockHandler(w http.ResponseWriter, r *http.Request) {
        clientIP := r.RemoteAddr
        log.Printf(" %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: \n\n")
        w.(http.Flusher).Flush()

        log.Printf(" 模拟回复完成,共输出 %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
}
</pre></div>
<p class="maodian"><a name="_label2"></a></p><h2>使用方法</h2>
<p>保存为 <code>mock_coze.go</code></p>
<p>运行:</p>
<div class="jb51code"><pre class="brush:bash;">go run mock_coze.go
</pre></div>
<p>前端保持原有调用方式(URL 指向 <code>http://localhost:8680/coze-chat</code> 即可)</p>
<p class="maodian"><a name="_label3"></a></p><h2>自定义回复内容</h2>
<p>只需修改 <code>fullResponse</code> 变量中的文本,支持任意 Markdown 格式。例如想测试负面评价:</p>
<div class="jb51code"><pre class="brush:go;">fullResponse := "这件帽衫不太行,颜色暗沉、版型臃肿,建议再看看其他款~"
</pre></div>
<p>或者测试超长回复、代码块、列表等,都可以随意发挥。</p>
<p class="maodian"><a name="_label4"></a></p><h2>总结</h2>
<p>这个小工具极大提升了前端开发效率:</p>
<ul><li>零成本、无限测试</li><li>完全还原真实流式体验</li><li>内容、速度可控</li><li>支持前后端联调</li></ul>
<p>推荐所有在做 Coze Bot 前端交互的同学都备一个,调试 UI、加载状态、打字动画时简直无敌好用!</p>
頁: [1]
查看完整版本: Go语言快速搭建一个API流式回复本地模拟接口