
Langfuse 前端大型功能架构用本地 Zustand Store、无 useEffect 数据流与虚拟列表治理高状态密度界面【免费下载链接】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/langfuseLangfuse 的前端包含 traces/observations 大表、sessions 事件流、experiments、prompts、evals、datasets 等大量高状态密度界面行选择、筛选器、抽屉、懒加载、批量操作、虚拟滚动全部集中在少数巨型组件里。本文基于 Langfuse 仓库中 frontend-large-feature-architecture 技能文档 及其引用的参考文档完整拆解其大型前端功能架构方法论控制器controller与视图分离、本地 vanilla Zustand store 的创建与订阅规范、无 useEffect的派生数据流、虚拟列表的行边界治理以及面向遗留代码的分片迁移路径。读完本文你能掌握在类似 Langfuse 这类数据密集型 React 应用中设计状态边界、拆分重组遗留巨型组件的完整实操方案。1. 适用场景与核心概念什么是 controller该技能定义了自己的触发场景构建、修改或重构大型前端界面时使用尤其涉及虚拟化列表、大表格、控制器组件、Zustand store、行选择、高频状态、渲染性能或者在添加useEffect/useMemo/useCallback、从加载数据派生表单默认值之前。文档给出了关键术语的严格定义在本技能中controller 指拥有功能逻辑的组件或 hook数据获取、视图状态、表格/列表状态、effects、actions 以及昂贵渲染。问题不在名字而在于一个地方拥有了太多可变职责。这个定义是整篇方法论的锚点Langfuse 的 traces、observations、experiments、prompts、evals、datasets、session 视图都存在controller-heavy界面仓库中仍有数百处待迁移的useEffect文档在撰写时统计web/src中有超过 350 个useEffect调用点。技能文档明确要求不要把现有大型 Langfuse 功能组件当作范例来复制除非它们已经遵循该技能否则一律视为迁移候选对象。完整的规则清单见 big-feature-rules.md。2. Big Feature Rules所有权基线与十条硬规则2.1 所有权基线Ownership Baseline规则文档首先给出状态归属的基线这是所有后续判断的法庭状态类别归属位置页面生命周期 / 功能域依赖页面/视图组件page/view创建并拥有服务端/查询状态tRPC / React Query路由状态router / filter hooks高频本地 UI 状态每次挂载一个的本地 feature store跨路由/跨功能的产品级状态全局 store仅此用途纯数据准备独立纯函数在渲染前把抓取的数据编译成UI 数据复杂用户工作流actions/*.ts文件或 store actionsEffects集成边界外部系统对接不是常规状态推导手段昂贵的行/单元格/条目视图只读view-only背后是窄容器数据流被要求单向抓取的数据 → 编译后的 UI 数据 → 渲染。2.2 十条硬规则Hard Rules功能生长通常意味着需要把 React 渲染与功能逻辑分离——更大的组件不是架构。大多数组件应当是 view-only要么渲染被给定的东西要么从 context 可用的 feature store 中读取一小块选中的值。复杂的数据准备放在独立纯函数中后端数据单向流动。触发复杂逻辑的用户操作放在渲染组件之外作为命名异步函数或 store actionaction 需要大量上下文时传入 feature store 实例让 action 自己取所需。同时存在本地 store 状态与 React Query 数据的功能需要显式桥接自定义 hook 或命名 action。页面实例级状态筛选器、选中行、展开行、懒加载状态、抽屉、本地 actions优先用 view-scoped 本地 store而不是全局 store。本地 store 实例用lazyuseState初始化器创建不用useMemo——store 是每次挂载的实例不是渲染期派生值。Effect 不应是常规状态变更器。添加 effect 前先尝试纯数据准备、store action、显式事件处理器。不要复制现有大型 Langfuse 功能组件作为范例除非遵循本技能否则按遗留处理。遵循 react-without-useeffect.md 中的黄金示例数据未就绪时不渲染 UI、从initialValueprop 播种状态、在渲染中派生值而不是用 effect 同步当改动改善了功能边界时更新该功能的 README 或迁移笔记记录改了什么、下一片是什么。2.3 Effects 与 Actions 的边界规则文档进一步划界Effect 只用于命名的外部系统集成订阅、observer、浏览器事件监听器、定时器、命令式第三方 API及其清理函数。放在容器或 feature hook 中不放视图组件里如果某个 effect 反复写状态就把对应 store action 做成幂等的。复杂 action 必须可以在不渲染组件的情况下被调用。组件负责接线 hooks 并传入依赖action 拥有工作流本身。文档给出的形态await applyBulkAction({ store, queryClient, projectId, });Action不得调用 React hooks把 hook 结果、query 辅助函数、本地 store 实例或窄回调依赖传进去。若 action 需要大量数据准备在旁边导出一个纯 helper让转换可以独立测试。反面模式同样被点名不要为了让一个按钮能做功能级工作而穿过整棵树传 20 个 props也不要因为页面 controller 恰好拥有全部依赖就把复杂工作流内联在页面里。3. React Without useEffect状态 → 帧的心智模型这是该技能的黄金模型文档react-without-useeffect.md核心命题是UI 是状态的纯函数。3.1 为什么写状态的 effect在机制上必然坏文档用游戏引擎类比UI 是一帧由纯函数从状态渲染。effect 写状态会机械性地破坏这个模型React 用不完整状态commit 并绘制一帧effect 在绘制后触发二次渲染修复这帧两帧之间用户可以操作、异步结果可以到达——修复步骤与真实输入产生竞态。这就是effect 重置了我的表单这类 bug 的来源。React 18 的并发渲染让时序更不可预测但模型本身已经是坏的本应一次纯渲染的地方变成了两次渲染加一个修复步骤。原则是保持渲染纯逻辑放到执行同步且归属明确的地方——事件处理器、命名 action、普通派生值。3.2 头号反模式effect 派生/准备数据文档引用了仓库中的真实案例 EditMonitorPage.tsxconst [liveName, setLiveName] useState(); useEffect(() { setLiveName(data?.name ?? ); }, [data?.name]);一个 effect 把抓取到的数据镜像进本地状态制造出两个事实来源、两者之间的时间窗口以及竞态用户在查询落定前编辑了名字effect 会覆盖他的输入。修复方式取决于值的性质纯派生值本地永不编辑在渲染中计算无状态无 effectconst title data?.name ?? 。加载数据播种可编辑状态此案例用下面的黄金拆分。3.3 黄金示例拆分组件用加载状态门控渲染拆成两个组件。外层是数据准备器 控制器拉取数据查询挂起期间渲染 loading 态优先匹配最终布局的 skeletonSpinner /是最低限度的兜底。内层接收加载好的值作为initialValueprop用useState(initialValue)播种——值保证已存在且稳定没有任何 effect 能覆盖它// 外层数据准备器 控制器。数据未就绪前不渲染 UI。 function EditMonitorPage() { const { data, isPending } api.monitors.get.useQuery({ projectId, id }); if (isPending) return Spinner /; if (!data) return ErrorPage titleMonitor not found /; return EditMonitorForm key{data.id} initialMonitor{data} /; } // 内层仅在数据存在后挂载。状态只播种一次。 function EditMonitorForm({ initialMonitor }: { initialMonitor: Monitor }) { const [liveName, setLiveName] useState(initialMonitor.name); // ... }这从根上消灭了加载前输入的整类竞态不存在表单没有数据就存在的时刻。key{data.id}在实体身份变化时重新挂载内层组件保证播种始终诚实。表单规则只有在所有初始值都已准备好之处才定义表单数据还在加载表单就放在更深的树里——DataPreparerAndController拉取、显示 loading然后把initialValues和onSubmit传给只负责渲染字段与提交的纯FormComponent。文档举了仓库中的真实案例 CreateOrEditLLMToolDialog.tsxuseForm在对话框顶部用 create 模式默认值创建之后一个编辑模式下填充表单的 effect 在现有工具可用时调用form.reset(...)。正确的修复是结构性的而非更好的 effect在渲染表单组件之前决定defaultValuescreate vs edit只在就绪时渲染表单reset effect 随之消失。3.4 从服务端状态派生客户端状态当客户端状态引用服务端数据选中的行、active id、选中的选项时只存用户意图id在渲染中通过与 query 数据合并派生有效值const selectedId useFeatureStore((s) s.selectedId); const selected rows.find((r) r.id selectedId) ?? null;不要写一个 effect 在 refetch 时校验或把服务端数据拷贝进客户端 store。派生模式让每个事实只有一个事实来源——store 拥有意图query 拥有数据——合并在 loading、refetch、失效过程中始终正确。只有当合并可测量地昂贵时才包useMemo。3.5 什么时候 useEffect 才合法Effect 用于触达 React 渲染之外的东西DOM 与浏览器 API——document.addEventListener/removeEventListener、observers、命令式第三方 API、Web Audio且需要用户手势。健康的 effect 具备三要素无依赖或极少的稳定依赖、单一关注点、有清理函数。3.6 useCallback / useMemo 是过早优化useCallback就是函数版的useMemo。不要在确认并测量过的性能问题之前做记忆化拆分组件就是记忆化的一种形式。到处都需要记忆化说明组件重渲染过于频繁意味着状态边界错了——修边界。唯一例外是把引用稳定性当作正确性要求当回调或对象是一个合法的集成 effect 或数据获取 hook 的依赖时记忆化它或提升到组件外避免依赖每次渲染变身份、导致 effect 循环——这是正确性不是优化。3.7 优先 UI 方案而非代码方案很多前端问题有 UI 解而不是代码解loading 态加门控渲染比保持行为的聪明重构删掉的复杂性更多。不要害怕改变行为来简化——在页面之前显示半就绪表单的地方渲染 skeleton 是改进而非回归。这也是为什么先写特征测试再保持行为重构很少适用于大型前端重构目标行为往往就是更简单的那个而不是当前的那个。4. 本地 Feature Store默认模式、创建方式与反模式local-feature-state.md 规定了本地状态的完整治理方案。4.1 目标与默认模式大型前端功能不应让一个组件或 hook 拥有一切——那种形态下一个复选框、hover 或行选择变化会重跑构建筛选器、列、数据包装器、昂贵单元格、抽屉、actions 和路由粘合代码的同一份代码。目标是让每个状态变化只唤醒语义上依赖它的 UI 与 actions。默认模式七步页面/视图用 lazyuseState创建一个 store 实例Context 只提供稳定的 store 实例组件订阅最小的有用切片变更逻辑放在命名 store actions 中复杂用户工作流放在actions/*.ts或 store actions 中昂贵单元格/行保持在窄容器之后的 view-only 状态大型功能根目录有一个简短的README.md所有者地图。只在状态高频、被挂载功能内多个子树共享、或必须跨行/条目重挂载存活时才加本地 vanilla Zustand store。4.2 为什么是本地而不是全局Langfuse 页面天然本地状态密集筛选器、保存视图、选中行、展开行、抽屉、peek 导航、懒行加载状态、视图本地 actions——这些状态通常属于一个已挂载的页面实例而非整个应用。本地 store 在页面/视图中创建、卸载时销毁让多个已挂载实例相互独立、避免跨路由状态泄漏并使所有权可见。全局状态保留给真正跨功能/跨路由的产品状态不要为了逃避 prop 钻取或让大组件变小而把状态提升为全局。同样不要为了让 PR 看起来有架构而加 store——如果当下问题是内联导出工作流、重复的筛选选项整形或庞大的列构建器先抽 action 或纯 helper只有当状态需要选择性订阅或必须在一个已挂载功能实例内跨行重挂载存活时才用 store。4.3 Store 创建lazyuseState而非useMemoconst [store] useState(() createFeatureStore({ initialProjectId: projectId, }), );这表达了真实生命周期一个 store 实例对应一个已提交的已挂载视图未使用的 setter 可以接受。useMemo是错的默认值——它是渲染期派生值的缓存不是外部 store 实例的所有权边界本地 store 是有状态的基础设施其身份应当按状态对待。useRef也能持有稳定实例但除非命令式 setup 需要 ref否则优先useState。保持 store 创建纯函数变化的路由/查询输入用命名 store action如resetForFeature(...)或init(...)同步进去。4.4 Store 形状与订阅用不可变纯对象承载需要 selector 友好的键控状态type FeatureStoreState { selectedIds: Recordstring, true; activeId: string | null; actions: { toggleSelected: (id: string, selected: boolean) void; setActiveId: (id: string | null) void; }; };避免原地变更Set/Map若使用更新时整体替换实例。selector 应返回原始值或稳定引用一个组件需要多个值时用 shallow selector 辅助或拆分订阅让一个字段的变化不重渲染无关 UI。4.5 独立 Actions组件接线 hooks、路由参数、store、analytics 与 query 辅助action 拥有工作流通过回调 refetch、读取传入的 store、调用纯 helper、执行浏览器副作用、发 analytics。Action 不得调用 React hooks工作流需要大量上下文时传入本地 store 实例或小型依赖对象而不是穿过视图组件传递长 prop 链await exportFeatureData({ capture, fetchDetails, projectId, refetchSummary, selectedIds, });对大量数据整形在旁边导出纯 helper让转换无需渲染页面即可测试。4.6 反模式清单表格/列表组件同时拥有选择、筛选、列、路由、peek 状态、批量操作、本地对话框和昂贵渲染单元格Context provider 的value随行选择、hover、滚动、active 行、展开行等高频状态变化只属于一个已挂载页面实例的本地 feature 状态被提升为全局 store用useMemo拥有本地外部 store 实例共享的src/components/*组件调用 feature-scoped store hook——这会悄悄破坏未挂载该 feature provider 的其他调用方view-scoped 的 Zustand 消费者必须放在src/features/*记忆化是唯一修复手段回调依赖内联配置对象每次渲染身份都变组件只需要一个布尔值却订阅大对象useEffect从抓取数据派生常规 UI 状态为了一个按钮能做 action组件用长 prop 链传 feature context页面组件把所有复杂异步工作流内联因为 hooks 恰好都在作用域里。4.7 本地状态迁移十一步先埋点识别哪个语义状态变化引起大范围渲染选最小有用边界store 状态、action 工作流、纯数据准备、命令式集成 hook仅在需要选择性订阅时把该状态组抽入本地 store用最小 UI 边界上的 selector 订阅替换宽 prop相关变更移入命名 actions稳定回调与数据包装器昂贵数据准备移入纯函数复杂用户 action 移入 store actions 或actions/*.ts外部函数更新 feature README改进了什么、还剩什么分散状态、下一个原子切片移除调试埋点对下一个状态组重复。5. 虚拟化列表渲染边界基础设施virtualized-lists.md 针对 Langfuse 实际使用的tanstack/react-virtualweb/package.json 中声明为^3.13.12给出专项规则。核心定性虚拟化列表是渲染边界基础设施——它只应计算哪些 item shell 可见并定位它们不应让每一行拥有 feature 状态、effects、订阅、数据加载和工作流。修改虚拟化界面前先找出当前调用点然后套用与任何大型功能相同的状态边界规则。5.1 智能陷阱Smartness Trap文档描绘了损坏的完整链路virtualizer 在滚动时重渲染父组件重建 callbacks、config、行包装器或数据对象行组件收到变化的 props尽管语义行没变行本地 effects/加载状态被重置或重新触发动态测量观察到了被外部变更者如 Google 翻译改过的 DOM测量更新 virtualizer 状态又把同一批行重渲染一遍。这不是一个小的记忆化 bug这是泄漏的状态所有权。 修复方向让滚动与测量状态只更新尽可能小的集成边界——滚动改变 virtual item offset 时未变化的行内容不应收到新的语义 props、不应重触发 effects、不应重建昂贵派生数据。5.2 Google 翻译的 DOM 行为浏览器翻译会在 React commit 之后变更已渲染 DOM包裹文本节点、替换文本、改变元素尺寸——全部在 React 数据流之外。React 与 TanStack Virtual 无从得知这些 DOM 变化代表稳定的翻译内容还是瞬态变更。文档的明确立场不要用translateno把产品 UI 排除在翻译之外除非产品明确如此选择Langfuse 必须能在浏览器翻译下正常工作。5.3 测量规则Measurement RulesTanStack 视为 item 的行元素上必须放正确的data-index文本密集型行上不要把活的measureElement与外部变更的翻译 DOM 混用简单行优先固定估值 overscan动态文本密集型行用受控测量ResizeObserver读行 shell、debounce 提交、活跃滚动期间不提交、高度取整避免亚像素抖动、调用virtualizer.resizeItem(index, height)若一行在两个高度间反复交替钳制到仍允许后续合法增长的最小高度。5.4 行规则Row RulesVirtualizer 只拥有定位必须跨重挂载存活的状态放在行实例之外昂贵行内容是记忆化的视图组件只接收稳定 props、不执行 effects窄行容器可以订阅本地 store 切片与 queriesFeature-scoped 行容器放在src/features/*共享的src/components/*行导出必须 context-free滚动可以重渲染 virtualizer但不应重渲染未变化的昂贵行内容不要用全局 store 在虚拟化间保存行状态——用已挂载列表/页面实例拥有的 view-scoped store。5.5 虚拟化迁移步骤加临时日志判断滚动引起的是重挂载、prop 变化、测量循环还是 query refetch发布前移除日志必须跨虚拟化存活的行本地状态移入本地 store稳定传给行的回调与 config 对象用固定估值或受控测量替换活的measureElement行逻辑移入纯 helper 或 feature 本地容器用开启浏览器翻译、水平缩放、小垂直滚动增量验证。6. Controller 迁移指南把巨型组件变成受管功能controller-migration.md 给出把已长成 controller 的前端界面迁到目标形态的完整路径。目标是清晰的所有权不是全部塞进 store。6.1 每个迁移 PR 必须书面记录本次针对的 controller 问题正在改进的状态/action/数据准备/渲染边界哪些行为是故意改变的、哪些必须保持不变——把渲染门控在 spinner/skeleton 后面的 UI 简化往往就是正确决定什么埋点或测试证明这个切片有效功能中仍分散着什么下一个推荐切片。这就是大型功能变成受管功能的方式。feature README 是活的所有者地图随功能推进原地更新。6.2 十四步迁移路径映射 controller列出组件拥有的每个状态组、query、派生值、effect、回调、action 和昂贵子渲染分类状态区分 server/query、路由、持久化浏览器、高频本地 UI、派生视图数据、命令式集成、一次性 modal/表单状态埋点一个症状挑一个具体交互行选择、滚动、筛选变化、抽屉打开、表单步骤变化、保存视图变化测量什么被重渲染、重挂载、refetch、重算选边界从高价值边界开始——选择、懒行状态、批量 action 工作流、筛选目标映射、列/视图状态、向导步骤状态、纯数据准备选最轻工具纯 helper 或 action 抽取可能是正确第一步只在需要选择性订阅或按挂载存活时才加本地 store需要时创建本地 store 实例lazyuseStatecontext 只提供这个稳定实例变更移入命名 actions组件负责用户事件而非工作流容器与视图分离容器可订阅、调 hooks、拉数据视图渲染 props 或极小的选中值数据准备移出渲染昂贵转换放纯函数后端数据流入编译后的 UI 数据再进入渲染显式桥接 query 状态本地 store 决策依赖 React Query 数据时用命名 feature hook 或 action 表达该关系隔离命令式集成虚拟化器、observers、键盘监听、第三方 DOM 变更处理、定时器都放在窄集成 hook 里更新 feature README记录本 PR 改进了什么、期望边界、已知的分散状态、下一个抽取目标移除调试埋点重复每个切片让一个语义交互变窄、更易推理。6.3 按功能选第一个切片Traces 与 observations 表从行选择、全选、批量 action 或昂贵单元格包装器开始Session 详情与 session 事件把虚拟化、懒行加载状态、动态测量与渲染行内容隔离开实验结果表选中行状态、筛选目标映射、run/evaluation 批量 action、比较列构建的纯 helper实验创建向导把已提交表单数据与显示状态active step、选中 prompt 标签、schema 显示名、评估器选择分开Prompt 管理拆分 prompt 详情路由/query 状态、label/version 选择、prompt 历史数据准备、mutation 工作流Eval 模板与评估器表单先抽表单默认值、model/provider 准备、校验 helper、提交工作流再加 storeDatasets 与 dataset runs隔离 active-cell/比较字段状态、表格选择、run 比较准备、上传/导入工作流。若某个功能已有部分 hooks视为部分迁移不是整个界面健康的证明。6.4 验收标准与禁忌验收标准本地状态变化只唤醒选中了该状态的组件页面组件不再因无关的行级变化重建列、筛选器、行包装器与 action 回调昂贵行/单元格是窄容器后的 view-onlyeffect 是外部系统集成边界而非初始化或常规数据推导复杂工作流可以在不渲染页面的情况下被调用feature README 告诉下一个开发者什么改进了、什么仍分散、下一个改进应瞄准什么。明确回避用巨型全局 store 替换巨型组件没有测量验收标准就一次搬完所有状态把记忆化当架构把 provider 耦合的 store hook 放进共享src/components/*导出因为页面恰好拥有全部依赖就把工作流留在页面内把 README 当胜利宣言而掩盖残余 controller 状态——剩余债务必须写明。7. Feature README面向人与 Agent 的所有者地图feature-readmes.md 规定大型前端功能文件夹应有简短README.md作为人和 agent 的所有者地图——优先README.md以匹配web/src/features/*现有约定仅当文件夹已有面向用户或生成的 README 时才用FEATURE.md。README 不是 changelog只描述持久边界并指向更深的迁移笔记。必需章节Surface该文件夹拥有的产品界面Entry Points挂载该功能的路由文件或父组件及它们调用的页面/视图生命周期 owner 文件Structure每个子文件夹拥有什么根components/只放功能内跨界面复用的组件页面 controller、本地 store、actions/、集成 hook、界面私有容器放在detail/等界面文件夹里External Consumers导入这些组件的其他功能——保持共享导出 context-free防止意外的 provider 耦合State Ownershipserver/query 状态、路由状态、本地 feature 状态、全局产品状态、DOM 集成状态、view-only props 各自在哪Performance And Stability Boundaries哪些交互高频或外部不稳定、哪些组件允许因它们重渲染或测量典型滚动与虚拟化更新、行选择/hover/展开/懒加载、筛选/保存视图/列状态变化、抽屉/peek/键盘导航、浏览器翻译等第三方 DOM 变更、resize 与动态行测量Migration State已改进什么、哪些状态/actions 仍分散、接下来一到两个原子切片Development Context扩展该功能前应读的 agent skills、迁移笔记或 issue 文档。更新风格要求原地更新而非 changelog例如当前形态中已改进本地 store 拥有行选择导出 action 移入actions/exportFeatureData.ts行视图不再订阅筛选状态。仍分散保存视图状态仍在页面 controller筛选选项准备仍内联mutation 工作流仍闭包页面 hooks。下一切片筛选选项准备抽成纯 helper批量 action 工作流移入 action 文件路由/query 粘合与视图组件分离。README 更新应与实际变更匹配状态/action 抽取只更新相关迁移状态条目新功能文件夹结构则要在逻辑移入前先写所有者地图与外部消费者。它对迁移中的功能必须诚实不要把部分迁移的功能呈现为最终模式不要等到完美重组才记录现状。8. 总结Langfuse 前端架构方法论的完整图景把 SKILL.md 的愿景段落作为收束抓取的数据单向流动query → 准备好的数据 → 渲染以就绪状态门控。状态从 props 播种、被处理器编辑、永不被 effect 镜像。Actions 是树外普通函数。留下的 effects 是带清理的薄 DOM/浏览器集成。仍有数百处不符合这个形态——当你碰到其中一处把它移向这个形态而不是扩展那个 effect。整篇技能文档的方法论可以压缩为一张分工表页面/视图拥有生命周期React Query/tRPC 拥有服务端状态router/filter hooks 拥有路由状态每次挂载的 vanilla Zustand store 拥有高频本地 UI 状态selector 返回原始值跨行重挂载存活actions/*.ts与 store actions 拥有复杂工作流纯函数拥有数据准备窄集成 hook 拥有虚拟化和 DOM 集成feature README 拥有迁移计划。仓库中 refactor-react-effects/SKILL.md 提供配套的 effect 审计与组件拆分配方可作为本方法论的执行工具。对维护 Langfuse 或任何同类数据密集型 React 产品的前端团队而言这套规则的实用价值在于它不是抽象品味而是给出了从埋点、分片、验收标准到文档留痕的完整可执行流程让巨型 controller这种普遍存在的技术债第一次变成可以被一个切片一个切片地偿还的工程对象。【免费下载链接】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),仅供参考