Langfuse In-App Agent 同步机制:Skills 目录与 System Prompt 的同步脚本实战指南
【免费下载链接】langfuse🪢 Open source AI engineering platform: LLM evals, observability, metrics, prompt management, playground, datasets. Integrates with OpenTelemetry, LangChain, OpenAI SDK, LiteLLM, and more. 🍊YC W23项目地址: https://gitcode.com/GitHub_Trending/la/langfuse
本文聚焦 Langfuse 开源仓库中scripts/in-app-agent/目录下的同步工具链,系统讲解两条核心同步链路:基于@repo/langfuse-skills包的 Skill 目录同步(sync/sync:check),以及基于sync-prompt.sh的 In-App Agent 系统提示词(System Prompt)跨云区域同步。读完本文,你将掌握 Langfuse 中"技能目录"与"托管提示词"的完整同步流程、种子数据写入原理、公共 API 手动同步与生产环境校验方法,能够直接复用于自己的 Langfuse 部署与二次开发。
一、同步机制总览:Agent 运行时需要什么
Langfuse 的 In-App Agent(应用内 AI 助手"Langfuse Assistant")运行时依赖两类可更新资产:
- Langfuse Skills 技能目录:一组面向 Coding Agent(如 Claude、Codex)的 Markdown 技能文档,随上游
langfuse/skills仓库演进,需要定期同步到本仓库的生成产物中; - 系统提示词(System Prompt):定义 Agent 身份、行为规则、工具使用偏好、权限边界与数据作用域的模板文本,以 Langfuse 托管 Prompt(版本化、可打标签)的形式供 Agent 在运行时加载。
这两条链路的维护脚本与文档全部位于 scripts/in-app-agent/README.md,其中 Skill 同步由@repo/langfuse-skills包内的脚本实现,Prompt 同步则分为"本地种子数据写入"与"跨云区域手动同步"两条路径。下面分别展开。
二、Skill 同步:将上游技能目录固化进仓库
2.1 技能目录的存放位置
通用 Langfuse 技能目录及其同步脚本位于@repo/langfuse-skills包内,即 packages/langfuse-skills。该包的核心结构如下:
src/index.js/src/index.d.ts:对外导出LANGFUSE_SKILLS只读数组,每个元素为{ name, description, instructions }三元组;src/generated/skills.js:由同步脚本自动生成的技能目录,文件头明确标注"generated ... Do not edit it manually";scripts/sync-skills.mjs:同步脚本本体;package.json:定义了sync与sync:check两个 npm script。
2.2 触发同步与校验
执行同步(拉取上游并覆写生成文件):
pnpm --filter @repo/langfuse-skills run sync执行校验(仅比对生成文件与上游是否一致,不修改任何文件):
pnpm --filter @repo/langfuse-skills run sync:check两个命令分别对应 package.json 中的"sync": "node scripts/sync-skills.mjs"与"sync:check": "node scripts/sync-skills.mjs --check"。在 CI 或提交前校验中,sync:check常被用作"生成产物是否与上游漂移"的门禁:一旦本地生成文件与上游不一致,脚本会以非零退出码失败并报错Generated skill catalog differs from upstream或Generated skill catalog is missing。
2.3 同步脚本的底层逻辑
从 scripts/sync-skills.mjs 的源码可以看到完整的数据流:
- 确定数据源:通过 GitHub API 拉取
langfuse/skills仓库中skills/langfuse/references目录下的 Markdown 文件列表,分支通过环境变量LANGFUSE_SKILLS_REF控制,默认main;若设置了GITHUB_TOKEN环境变量,请求会附带 Bearer Token 以提升 API 配额; - 解析每个技能文件:
parseSkill函数解析 Markdown 的 frontmatter(要求存在name与description字段,支持单引号包裹值的剥离),frontmatter 之后的正文作为instructions,三者构成一个完整的技能条目; - 渲染生成模块:将技能数组序列化后用 Prettier(babel parser)格式化,写入 src/generated/skills.js,文件头自动标注生成来源,提醒开发者勿手改;
--check模式:读取已存在的生成文件并与期望内容逐字节比对,不一致或文件缺失即抛错退出,一致则打印Generated Langfuse skills are in sync: ...并列出技能名。
从生成的技能目录可见当前包含langfuse-ci-cd、langfuse-cli、langfuse-dataset-construction、langfuse-error-analysis、langfuse-observability、langfuse-judge-calibration、langfuse-prompt-engineering、langfuse-prompt-migration、langfuse-sdk-upgrade、langfuse-setting-up-evals、langfuse-skill-feedback等技能,覆盖 CI/CD 门禁、CLI 参考、数据集构建、错误分析、可观测性、评测搭建等 Coding Agent 高频任务。
2.4 技能目录如何被 Agent 运行时消费
同步进仓库的技能目录并不是摆设,而是被 In-App Agent 运行时直接装载。见 worker/src/features/in-app-agent/runtime/skills.ts:
import { createSkill } from "@mastra/core/skills"; import { LANGFUSE_SKILLS } from "@repo/langfuse-skills"; export const LANGFUSE_IN_APP_AGENT_SKILLS = LANGFUSE_SKILLS.map((skill) => createSkill(skill), );即运行时通过 Mastra 的createSkill将目录中的每个技能包装为可被 Agent 调用的 Skill 工具。因此,sync命令的本质是"把上游技能的最新内容同步为运行时可直接消费的仓库产物",保持这条链路畅通,Agent 才能始终使用最新的技能指令。
三、Prompt 同步:System Prompt 的种子写入
3.1 提示词模板的规范位置
In-App Agent 的规范系统提示词位于 packages/shared/src/in-app-agent/server/systemPrompt.ts,导出的常量为IN_APP_AGENT_SYSTEM_PROMPT_TEMPLATE。这是一个带 XML 标签分区的模板,包含以下语义区块:
| 区块 | 职责 |
|---|---|
<identity> | Agent 身份:"You are an assistant called Langfuse Assistant" |
<behavioral_rules> | 行为守则:不确定时直说、回答前先检索 Langfuse 文档、不评价自身行为、简洁克制等 |
<tools> | 工具偏好:优先使用 Langfuse MCP 工具、用 docs 工具查文档、按需选用 Langfuse skills |
<code_generation> | 代码生成边界:推荐引导用户使用自有环境的 Coding Agent |
<data_scope> | 数据作用域:默认排除内部环境(占位符{{sidebarHiddenEnvironments}}) |
<data_model> | 数据模型:traces/observations 关系、指标聚合位置 |
<permissions> | 权限边界:涉及变更的工具需用户显式确认 |
<user_navigation> | 页面导航建议(占位符{{redirectToolName}}) |
{{sandboxFilesystem}} | 沙箱文件系统上下文占位符 |
源码注释还揭示了一个关键设计:时钟、用户与屏幕上下文是按每次模型调用追加的,不编译进模板,从而避免使"工具 + 系统提示"的缓存前缀失效。模板中的{{sidebarHiddenEnvironments}}、{{redirectToolName}}、{{sandboxFilesystem}}均为运行时注入的占位变量。
3.2 本地 Seeder 如何写入提示词
本地 Postgres 种子脚本会导入上述模板模块,并在种子项目中创建名为in-app-agent-system-prompt的文本类型 Prompt。核心逻辑位于 seed-postgres.ts 的upsertInAppAgentSystemPrompt函数:
- 项目:种子项目 ID 为
7a88fb47-b4e2-43b8-a06c-a5ce950dc53a; - 名称与类型:
name: "in-app-agent-system-prompt",type: "text"; - 标签:
labels: ["production", "latest"],即"生产可用 + 最新版本"双标签,运行时可按标签稳定取用; - 版本:
version: 1,使用 Prisma 的prompt.upsert按projectId + name + version唯一键写入,首次创建,后续更新则刷新prompt内容与标签。
这意味着本地开发环境与 PR 预览环境无需手动操作即可获得与生产一致的 Agent 系统提示词。
四、手动同步:跨云区域发布 System Prompt
4.1 适用场景与前置条件
当需要在 Langfuse Cloud 各区域(EU / US / JP / HIPAA)通过公共 API 创建该提示词时,使用 scripts/in-app-agent/sync-prompt.sh。其关键语义是幂等新增版本:如果某个区域已存在同名 Prompt,同一次 API 调用会改为新增一个版本,而不是覆盖历史版本,从而保留完整的版本演进记录。
运行脚本前,需要为所有目标云区域设置项目凭据(公钥 + 私钥),逐一导出环境变量:
export LANGFUSE_AI_FEATURES_EU_PUBLIC_KEY="pk-lf-..." export LANGFUSE_AI_FEATURES_EU_SECRET_KEY="sk-lf-..." export LANGFUSE_AI_FEATURES_US_PUBLIC_KEY="pk-lf-..." export LANGFUSE_AI_FEATURES_US_SECRET_KEY="sk-lf-..." export LANGFUSE_AI_FEATURES_JP_PUBLIC_KEY="pk-lf-..." export LANGFUSE_AI_FEATURES_JP_SECRET_KEY="sk-lf-..." export LANGFUSE_AI_FEATURES_HIPAA_PUBLIC_KEY="pk-lf-..." export LANGFUSE_AI_FEATURES_HIPAA_SECRET_KEY="sk-lf-..." ./scripts/in-app-agent/sync-prompt.sh也可以把上述 export 语句移入.env文件,在子 shell 中加载后运行,避免污染当前 shell 环境:
(source .env; ./sync-prompt.sh)脚本假设curl与jq已安装且位于PATH中,两者分别承担 HTTP 请求与 JSON 构建。
4.2 脚本执行流程(源码级拆解)
对照 sync-prompt.sh 源码,脚本的核心流程如下:
- 定位模板文件:脚本基于自身路径反推仓库根目录,读取
packages/shared/src/in-app-agent/server/systemPrompt.ts;若文件缺失,立即报错退出(set -euo pipefail保证任何一步失败即中止); - 加载提示词内容:模板是纯可擦除 TypeScript(plain erasable TS),脚本借助 Node 原生的类型擦除能力直接
import()该.ts模块,无需构建步骤,取IN_APP_AGENT_SYSTEM_PROMPT_TEMPLATE导出值作为提示词正文; - 构建请求体:用
jq -n构造 POST 请求 JSON:
{ "name": "in-app-agent-system-prompt", "type": "text", "prompt": "<模板正文>", "labels": ["production", "latest"], "commitMessage": "Sync in-app agent system prompt" }- 预检阶段(Preflight):脚本定义区域矩阵
REGIONS=(STAGING EU US JP HIPAA)与对应BASE_URLS(staging.langfuse.com、cloud.langfuse.com、us.cloud.langfuse.com、jp.cloud.langfuse.com、hipaa.cloud.langfuse.com)。对每个区域:- 检查对应公钥/私钥环境变量是否已设置,缺失则记录预检错误;
- 用
curl --user "公钥:私钥"发起对${BASE_URL}/api/public/v2/prompts/${PROMPT_NAME}的访问探测,仅当返回 200(存在)或 404(不存在)才视为通过,其余状态码(如 401/403)记录为预检错误; - 若存在任何预检错误,脚本打印
Preflight failed; no regions synced.并整体退出,保证"要么全部通过,要么一个都不同步";
- 逐区域确认并同步:预检全部通过后,脚本对每个区域执行
read -r -p交互式确认(Create or add a new version of in-app-agent-system-prompt in <REGION> (<BASE_URL>)? [y/N]),只有输入y/yes才继续;确认后向${BASE_URL}/api/public/v2/prompts发送POST(Basic Auth +Content-Type: application/json,--fail让任何非 2xx 响应直接导致脚本失败); - 汇总结果:脚本统计
SYNCED_REGIONS数组,最终打印Synced in-app-agent-system-prompt to regions: EU US ...,若全部跳过则输出No regions synced.。
值得强调的是"先预检、后确认"的两段式设计:预检阶段不会写任何数据,只验证凭据有效性、网络可达性与区域配置,避免在确认前因凭据错误而部分写入;真正的写入发生在用户逐区域确认之后,防止误操作。
五、同步结果的验证
同步完成后,可用 Langfuse CLI 拉取指定标签的 Prompt 进行验证。以 EU 区域为例:
LANGFUSE_PUBLIC_KEY="$LANGFUSE_AI_FEATURES_EU_PUBLIC_KEY" \ LANGFUSE_SECRET_KEY="$LANGFUSE_AI_FEATURES_EU_SECRET_KEY" \ LANGFUSE_BASE_URL="https://cloud.langfuse.com" \ langfuse api prompts get in-app-agent-system-prompt --label production校验其他区域时,将三个环境变量替换为对应区域的公钥、私钥与 Base URL 即可:
| 区域 | Base URL |
|---|---|
| EU | https://cloud.langfuse.com |
| US | https://us.cloud.langfuse.com |
| JP | https://jp.cloud.langfuse.com |
| HIPAA | https://hipaa.cloud.langfuse.com |
该命令通过--label production拉取生产标签下的当前版本,可确认远端 Prompt 内容与 systemPrompt.ts 模板保持一致——这正是源码注释中强调的约束:保持模板与托管 Prompt 同步,因为生产运行时从 Prompt 管理加载提示词,而本地开发与种子数据使用该模板。
六、日常维护清单
综合上述链路,In-App Agent 资产的日常维护可归结为三个动作:
- 技能目录更新:上游
langfuse/skills有更新时,执行pnpm --filter @repo/langfuse-skills run sync重新生成 skills.js 并提交;CI 中用sync:check防止漂移; - 提示词模板更新:修改 systemPrompt.ts 后,本地开发由 Seeder 自动 upsert(见 seed-postgres.ts),云端各区域则通过 sync-prompt.sh 手动发布新版本;
- 发布后校验:用
langfuse api prompts get ... --label production逐区域核对生产标签下的 Prompt 内容与版本。
通过"模板单一来源(Single Source of Truth)+ 生成产物 + 托管 Prompt"三层结构,Langfuse 既保证了 Agent 运行时资产的版本可控与可回滚(每次同步生成新版本而非覆盖),又让本地开发、预览环境与多区域云环境之间的资产保持一致,这正是 scripts/in-app-agent/README.md 所描述的同步体系的核心价值。
【免费下载链接】langfuse🪢 Open source AI engineering platform: LLM evals, observability, metrics, prompt management, playground, datasets. Integrates with OpenTelemetry, LangChain, OpenAI SDK, LiteLLM, and more. 🍊YC W23项目地址: https://gitcode.com/GitHub_Trending/la/langfuse
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考