跳到主要内容

coze-loop 与 Langfuse 提示词管理:横向对比与建议

约 8 分钟2,085 字更新于 2026/10/04

返回 概览 · 详细报告:coze-loop · Langfuse · 交互页面

  • coze-loop 提交:3a6a2bf0。Langfuse 提交:f75c661d。
  • 每个单元格都带源码永久链接。"建议"一节是基于证据的推断,已单独标注。

1. 一张图看差异​

2. 对比矩阵​

2.1 数据模型与存储​

维度coze-loopLangfuse
数据库MySQL,JSON 文本列。convertor/manage.go#L158-L200Postgres(Prisma),Json 列。schema.prisma#L786-L813
提示词实体头表 prompt_basic + 草稿表 + 提交表。prompt.go#L12-L45无父表。同名版本行的集合就是提示词。schema.prisma#L786-L813
租户space_id。prompt_basic.sql#L1-L24projectId。schema.prisma#L786-L813
内容类型统一为消息列表。角色含 placeholder。支持多模态片段。prompt_detail.go#L56-L111text(字符串)或 chat(消息数组,含 placeholder)。types.ts#L25-L29
模型配置强类型 ModelConfig,用 ModelID 引用模型注册表。prompt_detail.go#L193-L242自由 JSON config,服务端基本不解释。promptToolConfig.ts#L59
工具内联在提示词中;另有独立版本化的工具子系统。toolmgmt/tool.go#L8-L46放在 config 中,实验时解析。promptToolConfig.ts#L59
删除软删除 basic,提交保留。infra/repo/manage.go#L157-L181硬删除版本行;latest 重挂到最高剩余版本。deletePrompt.ts#L96-L123
分类无标记;有安全级别 L1–L4。prompt_basic.go#L8-L35tags[](GIN 索引)+ 名字中的 / 虚拟文件夹。createPrompt.ts#L419-L691

2.2 版本与标签​

维度coze-loopLangfuse
编辑模型每用户私有草稿,800 ms 防抖自动保存。use-prompt.ts#L238-L285无草稿。每次保存创建新版本。createPrompt.ts#L93-L290
版本号用户指定的严格 semver,不校验递增。application/manage.go#L578-L639系统分配的整数,latest + 1。createPrompt.ts#L160-L175
提交说明description。prompt_commit.sql#L1-L29commitMessage,≤ 500 字符。types.ts#L37-L86
标签存储独立映射表,DB 唯一约束保证 1 标签 1 版本。prompt_commit_label_mapping.sql#L1-L19行上的数组,应用代码在事务中保证唯一。updatePromptLabels.ts#L3-L43
预置标签production、beta、test(配置)。prompt.yaml#L18-L22latest(自动)、production(默认读取)。constants.ts#L1-L2
标签权限无角色模型,开源版只查空间成员。foundation/application/auth.go#L30-L70受保护标签 + 独立 RBAC 动作。authorizeProtectedLabelMutation.ts#L70-L152
并发控制所有写先 FOR UPDATE 锁 basic 行。manage.go#L536-L546创建不加锁,靠唯一索引 + 重试;改标签锁目标行。createPrompt.ts#L222-L236
变更通知事件收集器为空实现。event_collector.go#L51-L62每次写发事件,驱动 webhook / Slack。promptVersionProcessor.ts#L26-L115
审计创建、更新、提交时做内容审核(fail open)。audit.go#L32-L75每次写记审计日志。prompt-api-service.ts#L41-L96

2.3 模板与组合​

维度coze-loopLangfuse
引擎normal(fasttemplate)、jinja2(gonja 沙箱)、go_template。prompt_detail.go#L400-L422正则 {{var}},无条件和循环。prompts.ts#L14-L31
变量类型字符串、布尔、整数、浮点、对象、数组、placeholder、multi_part。prompt_detail.go#L113-L142文本变量 + placeholder(消息数组)。compileChatMessages.ts#L21-L91
未知变量normal:原样保留。prompt_detail.go#L400-L422原样保留。prompts.ts#L14-L31
安全限制10 s 超时、1 MB 输出、禁用 include、range ≤ 10,000。jinja_template.go#L21-L104无需沙箱(无表达式能力)。prompts.ts#L14-L31
组合语法<cozeloop_snippet>id=N&version=V</cozeloop_snippet>。snippet_parser.go#L33-L78@@@langfusePrompt:name=X|version=N@@@ 或 label=L。parsePromptDependencyTags.ts#L3-L61
引用方式按 ID + 固定版本。prompt_relation.sql#L1-L15按名字 + 版本或标签,延迟绑定。schema.prisma#L815-L833
深度 / 环最多 2 层。service/manage.go#L471-L597最多 5 层,检测环。PromptService/index.ts#L267-L284
片段内容只取片段第一条消息的内容。service/manage.go#L514-L533只能引用 text 提示词。PromptService/index.ts#L329-L349
防止断引用片段不可删除。application/manage.go#L255-L285阻止删除或移走被依赖的版本 / 标签。deletePrompt.ts#L56-L92

2.4 获取与缓存​

维度coze-loopLangfuse
接口POST /v1/loop/prompts/mget,批量。openapi.thrift#L7-L17GET /api/public/v2/prompts/{name},单个。promptNameHandler.ts#L17-L54
鉴权PAT Bearer。pat_verify.go#L20-L69项目 API Key(Basic)+ prompts:read。createAuthedProjectAPIRoute.ts#L229-L254
默认版本latest_version。service/manage.go#L221-L307production 标签。getPromptByName.ts#L21-L56
读取草稿支持:版本 $Draft。openapi.go#L473-L485无草稿概念。
返回内容已展开片段的提示词 + 模型配置 + 工具。openapi.go#L383-L577已解析依赖的提示词 + resolutionGraph,不渲染变量。promptNameHandler.ts#L40-L53
限流每空间 500 QPS,fail open。openapi.go#L579-L599不限流。RateLimitService.ts#L280-L285
服务端缓存只有标签→版本(TTL 60 s);提示词缓存为空实现。redis/prompt_label_version.go#L54-L161缓存已解析提示词(TTL 1 h)。PromptService/index.ts#L167-L178
失效方式按键删除;带标签提交时漏删。manage.go#L881-L951项目级 epoch 轮换,所有写路径都调用。PromptService/index.ts#L217-L241

2.5 发送给 LLM 与追踪​

维度coze-loopLangfuse
渲染位置服务端。formatter.go#L37-L60客户端 SDK / 浏览器 / 实验 worker。promptNameHandler.ts#L40-L53
服务端执行有:Playground、调试、PTaaS、内部执行。openapi.go#L601-L917只有实验和 Playground 代理。experimentServiceClickhouse.ts#L159-L246
模型接入eino,9 种协议。eino/init.go#L35-L69Vercel AI SDK 封装。llmText.ts#L175-L260
工具循环最多 50 步 / 30 分钟;工具结果只来自 mock。service/execute.go#L61-L227已读代码中未见多步工具循环。实验对每个条目调用 1 次 generateLLMText。experimentServiceClickhouse.ts#L214-L243
参数传递缺口ToolChoice、Thinking、Extra 未传给运行时。chat.go#L23-L70—
版本关联执行时 span baggage 带 key 和 version。service/execute.go#L359-L399摄取时按名字 + 版本回查,写 prompt_id。IngestionService/index.ts#L1294-L1326
每版本指标调试日志记录 token 和耗时。prompt_debug_log.sql#L1-L25UI 展示每版本延迟、token、成本、评分。promptRouter.ts#L1293-L1363

2.6 主要风险​

风险类别coze-loopLangfuse
权限UpdateCommitLabels 和片段引用可能跨空间。application/manage.go#L963-L993普通 API Key 可推动受保护标签(设计如此)。authorizeProtectedLabelMutation.ts#L70-L152
缓存一致性带标签提交后标签缓存最多 60 s 陈旧。manage.go#L881-L951任一写操作让整个项目缓存冷启动。PromptService/index.ts#L217-L241
原子性各写操作都在事务中。manage.go#L760-L953删除路径非原子。deletePrompt.ts#L96-L123
密钥模型 API Key 写入请求记录表。runtime.go#L263-L288未发现同类问题(在已读代码范围内)。
版本语义低版本可成为 latest。manage.go#L816-L826整数自增,无此问题。createPrompt.ts#L160-L175

3. 自建提示词库的建议​

以下是推断,不是源码事实。每条都注明了依据。

3.1 应该采用​

  1. 版本不可变,标签做发布指针。
  2. 用数据库约束保证"1 标签 1 版本"。
  3. 默认读取一个明确的发布标签,例如 production。
  4. 系统分配单调版本号;semver 可作为可选显示名。
  5. 受保护标签 + 独立权限动作。
  6. 缓存解析后的结果,用 epoch / 代际号失效。
    • 依据:Langfuse 的项目级 epoch 一次性解决传递依赖失效。PromptService/index.ts#L217-L241
    • 改进:按"依赖闭包"或按提示词名分代,减少冷启动范围。
  7. 所有写路径统一走一个"写后钩子":失效缓存 + 审计 + 事件。
  8. 追踪中记录提示词名 + 版本,并能按版本统计指标。

3.2 按需选择​

选择选 A 的理由选 B 的理由
草稿:每用户私有(coze-loop)vs 无草稿(Langfuse)编辑中间态不污染版本历史模型简单;需要冲突检测时再加
渲染:服务端(coze-loop)vs 客户端(Langfuse)统一行为;支持 PTaaS获取接口轻;可离线缓存
模板:多引擎(coze-loop)vs 极简正则(Langfuse)条件、循环、类型化变量无需沙箱;跨语言 SDK 易实现一致
引用:固定版本(coze-loop)vs 标签延迟绑定(Langfuse)可复现片段更新自动传播

3.3 应该避免​

3.4 最小可行数据模型(建议)​