构建、采用、回馈:我们如何借助开源 CopilotKit 重建 fynk 的 AI 助手

Constantin Wintoniak
发布于 2026 年 11 月 2 日 · 阅读时长 12 分钟

我们用开源方案替换了自研的 AI 聊天功能,还自己动手写出了这个框架的 Vue 版本。
-
采用标准:AG-UI 和 CopilotKit 让 fynk 少了 11,000 行自研代码
-
与其 fork,不如回馈:我们的 Vue 版本现已并入 CopilotKit
-
只造属于自己的部分:合同工具、权限和引用
我们应用内的助手,比它替换掉的那套聊天功能少了约 11,000 行自研代码。它所用的框架,直到 2026 年 5 月,在我们使用的技术栈里还根本不存在。我们的一位工程师 Abel Enekes 写出了这部分,并把它贡献给了项目。下面说说为什么这么做,以及我们会给任何想在自己产品里加入 AI 智能体(agent)的创始人或业务负责人什么建议。

2026 年 8 月,我们上线了 fynk assistant:一个智能体,能回答合同相关问题、对比合同,还能替你创建文档、给文档打标签、移动文档。发布文章里展示了它的能力。这篇讲的是它如何构建,以及哪些部分我们决定不自己造。
我们最初的 AI 聊天功能有什么问题?
它一次只能围绕一份文档回答问题,而且每加一个新功能,都得先改应用、再改 AI 服务。2026 年初,fynk 有一套自研的文档对话功能:打开一份合同,提一个问题,得到答案,并附带指向相关条款的链接。它能用,客户也在用。

回答里的每一段内容,都装在我们自己定义的消息格式里。下面是 2026 年 1 月服务器返回的「通知期为三个月」这句话的第一个词:
{
"status": "ok",
"message": {
"type": "AIMessageChunk",
"id": "…",
"content": "The notice period",
"additional_kwargs": {},
"response_metadata": {}
},
"bounding_boxes": null
}
说白了就是:一段文本,套在我们自己编的字段里,还留了个槽位放 PDF 坐标。
这个格式只认得两样东西:一段文本,以及它在 PDF 中的位置。想加别的,就得新增字段,而且前后端和 AI 服务都得同步改完,功能才能上线。要对比两份合同,就得改格式;要展示表格,前端就得加一种新的消息类型;要让智能体问一句“需要我帮你打开吗?”,就得在手工维护的状态机里再加一个状态,旁边还挂着一条不太靠谱的 WebSocket 连接。
如果你不写代码,可以这样理解:用户看不到这些工作,但每个新功能都依赖它。我们反复在造的,是每家做 AI 智能体的公司都要造的那套基础设施。既然这样,就不该再自己造了。
为什么换用开放协议?
因为应用内智能体的难点,在每个产品里都差不多,而已经有人把它们标准化了。
2026 年初,我写信给 Abel,建议把“AI 交互结构的大部分”迁移到 AG-UI 这样的标准上。他从 2025 年秋天起就在看相关资料。今天助手里同一句话长这样:
{ "type": "RUN_STARTED", "threadId": "…", "runId": "…" }
{ "type": "TEXT_MESSAGE_START", "messageId": "m1", "role": "assistant" }
{ "type": "TEXT_MESSAGE_CONTENT", "messageId": "m1", "delta": "The notice period" }
{ "type": "TEXT_MESSAGE_END", "messageId": "m1" }
{ "type": "RUN_FINISHED", "threadId": "…", "runId": "…" }
用大白话说:只有五个标准事件,任何 AG-UI 界面都能读。
同一句话用了更多行,那为什么反而更好?因为下一次提问不需要再发明新格式。让助手去比较两份合同,同一条事件流里自然会多出几种事件(简化版):
RUN_STARTED
TOOL_CALL_START Read Supplier agreement A
TOOL_CALL_END
TOOL_CALL_START Read Supplier agreement B
TOOL_CALL_END
TEXT_MESSAGE_CONTENT "I read both agreements. Three terms differ:"
STATE_SNAPSHOT { documents in context: 2 }
RUN_FINISHED
用大白话说:助手把每一步都报出来,界面就能一步步展示给你看。
这套东西没有任何 fynk 特有的部分,而这正是关键所在。我们的 AI 服务负责运行 agent,它用开源框架 LangGraph 搭建,再由一个 AG-UI 适配器把输出转成 AG-UI 事件。后端保存会话线程和历史记录,前端用 CopilotKit 渲染这些事件。agent 与界面之间的事件走标准协议,而对话历史留在 fynk 自己的后端。

框架不支持你的技术栈时,你该怎么办?
你可以 fork 它、等它支持,或者自己动手贡献代码。每条路都有代价,值得摊开来讲清楚。CopilotKit 原本只支持 React,而 fynk 用的是 Vue 应用。
Fork(分叉) 大概能管一个月。之后你就得一个人维护别人的代码库,上游每修一个地方,你都得手动合并。
等,是免费的——除非你要的那个功能,正好也是客户在等的。
共建,前期最贵。你得达到维护者的标准、贴合他们的测试、跟上他们的节奏。换来的回报是:你不再是唯一在乎这份代码的人。
我们选了共建。Abel 二月就开工,本以为用编程助手写「几行代码」就行。结果他的 PR 横跨 244 个文件、共 62,517 行,而且是照着 CopilotKit 自己的 React 测试套件先写测试、再写代码。维护者审了,该改架构的地方改了,2026 年 5 月 13 日合并。当天晚上,@copilotkit/vue 就挂上了 npm。
我本来只想省几行代码。真难的是从「能跑」变成「跑得和 CopilotKit 一样」。
—— Abel Enekes,fynk 软件工程师
大部分收益其实来自合并之后。五月至今,CopilotKit 团队和其他贡献者陆续发了二十多项 Vue 修复和功能,我们一行都没写:线程抽屉、文档、human-in-the-loop(人工介入流程)修复、无障碍支持。Abel 自己也继续贡献,到现在已经合并了五个 PR。当初要是 fork,这些我们一样都拿不到。
小团队加编程助手,现在能扛多大的活?
比一年前敢想的要多。搁以前,想把一个框架移植到维护者愿意接收的程度,得安排一整个开发团队。这次我们只有一个工程师,还是在他的本职工作之外完成的:二月首次提交,到五月合并大约三个月;到十月文档收尾,前后八个月。
这八个月让我们的代码库少了约 11,000 行,还白白拿到了二十多项 Vue 改动。我们是一家 25 到 30 人的公司,再选一次,还是这么选。
时间投入不是唯一的代价。参与开源意味着两条战线同时开工:一边是自己的产品,一边是项目的代码评审。对我们来说这还在可控范围内——Abel 提交 PR 的当天,维护者就完成了评审,架构上的问题由他们自己动手修,大约两周后合并。另外,客户已有的对话(包括历史记录)都要迁到新架构上,这本身就是一项实打实的工作。
作为团队,让我们意外的是精力到底花在了哪里。大部分精力都用在「告诉 agent 该做什么」和「检查结果对不对」上:先移植测试,再写代码;把决策写进 AGENTS.md 和一份新旧对齐文档(parity document),而不是每次都在提示词里重复一遍;还要逐个确认每个测试真的做到了它名字所说的那件事。
Abel Enekes,fynk 软件工程师
我要求的是一比一的测试,拿到的是一比一的测试名字。
应用内的 agent,凭什么让人放心把合同交给它?
主要就两点:你能看见它在做什么,并且能在它改动任何东西之前叫停。

AG-UI 让 agent 和界面之间保持一份共享状态的同步。在 fynk 里,这份状态存的是当前上下文中的文档。打开一份合同,助手就已经把它挂上了,所以一句「这里面的通知期是多久?」就能直接得到答案。在整页聊天界面里,输入 @ 就能添加文档,而且文档会一直挂着,方便你接着追问。切换到别的页面时,对话也不会中断,所以你可以先问一个宽泛的问题,再打开合同继续聊下去。对提问的人来说,这意味着不用复制粘贴,也不用解释自己指的是哪份合同。
2. 聊天里的工具调用:它的每一步你都看得见

Agent 调用的每个工具都会作为独立事件送达,CopilotKit 再把它们渲染到对话线程里。每条回答都带一个可折叠的“Finished in N steps”过程记录:读了哪些文档、搜了什么、改了什么,失败的步骤也会显示出来。合同场景下,用户需要核对 agent 到底做了什么,这份记录正好满足需求。
3. 人在回路:先询问,再执行

Agent 可以暂停当前运行,等待用户确认。只要涉及数据变更,我们都用这个机制。打开文档前,它会先问一句;把合同从签署状态撤回前,它会弹出确认框说明后果(“这会取消当前签署流程,并使已有签名失效”),然后等待用户点击。这个决定在产品层面就定下了:助手每次都问,用户之后可以自行决定是否给它更大权限。
在旧版对话系统里,这种卡片要在五个地方改代码:
-
自有消息格式里新增一种消息类型
-
AI 服务,负责发送消息并等待回复
-
前端,负责读取消息
-
状态机,新增一个等待状态
-
WebSocket,负责把答案传回去并恢复运行
按以前的估算,这大约需要两周。现在只需改两个地方,大约两天:agent 暂停运行,一个 Vue 组件展示卡片并把答案送回。
4. 生成式 UI:用我们自己的组件渲染表格和列表

纯文本并不适合用来“比较这两份供应商协议”。助手可以在聊天窗口里直接渲染我们自己的组件,所以对比结果会以真正的表格返回,每项条款并排展示,还能下载成 CSV 或 Excel。文档列表也一样:直接根据工具返回的结果渲染,而不是让模型重新敲一遍。这张表可以原样转发给 CFO。
5. 引用与权限:你能做什么,它才能做什么,仅此而已

这部分是我们自己做的。点击带编号的引用,fynk 会把合同滚动到对应条款并高亮,核对答案只需一秒钟。助手拥有的权限和你完全一样:它只能看到你能看到的合同,也只能修改你有权修改的内容。如果某个模板需要审批,助手也会等待审批通过。如果你让它把这类合同发出去签署,它会告诉你还有哪个检查点没完成。所有 AI 处理都在欧盟境内完成,你的数据绝不会被用来训练 AI 模型。
Viola Dittmann,Advancis 法务团队负责人
最让我们印象深刻的是它用起来非常自然。像问同事一样提问,就能得到专业、可靠的回答。现在已经离不开它了。
用你自己的合同体验这五个构建模块。
哪些该自己造,哪些该直接采用?
只造能让产品与众不同的部分,其余每个智能体都需要的能力直接采用。如果你也要把智能体放进自己的产品,以下是我们当时的取舍思路:

| 层级 | 自建还是采用 | 决策依据 |
|---|---|---|
| 聊天界面、流式输出、消息列表 | 采用(CopilotKit) | 引入 CopilotKit 之前,我们大部分聊天代码都集中在这一层。替换之后,fynk 减少了约 11,000 行代码。 |
| Agent 与 UI 之间的通信格式 | 采用(AG-UI) | 在我们自己的消息格式里,每加一个新功能就得加一个新字段,前端和 AI 服务两端都要跟着改。AG-UI 已经有现成的事件类型,覆盖文本、工具调用、状态和暂停等待用户操作。 |
| 共享状态、工具渲染、human in the loop(人工介入) | 采用(AG-UI、CopilotKit) | 我们之前手写了一套状态机,一次只能处理一个文档。CopilotKit 已经能处理多个文档、工具调用以及暂停等待用户。 |
| 工具本身 | 自建 | 从模板创建、移动阶段、搭建仪表盘。助手用的工具和我们的 API、MCP 服务器是同一套,每个只需写一次。 |
| 权限与审批检查点 | 自建 | 这套逻辑本来就存在于 fynk 中。助手以用户身份调用它,所以检查点拦住助手的位置,和拦住人的位置完全一致。 |
| 引用跳转到原文 | 自建 | 要跳到 § 12 并高亮,得靠我们自己的文档查看器。这部分我们保留自研,基于第一版聊天已有的条款链接来实现。 |
| 数据和 AI 在哪里运行 | 尽早决定 | 客户在问助手能做什么之前,先问他们的合同在哪里处理。fynk 托管在欧盟境内、通过 ISO 27001 认证的数据中心。所有 AI 处理都留在欧盟,你的数据绝不会被用来训练 AI 模型。我们的安全页面列出了每一家服务商。 |
如果你是一位创始人,正在权衡要不要把更多技术栈自己造,我们写下了哪些合同工作流值得自建、以及在哪些环节会行不通。
常见问题
-
CopilotKit 支持 Vue 吗? 支持。从 2026 年 5 月 13 日起,
@copilotkit/vue包就是 CopilotKit 的一部分。当天维护者合并了 fynk 贡献的 Vue 移植版本。它覆盖聊天组件、共享状态、工具渲染、生成式 UI 和 human in the loop。 -
AG-UI 和 CopilotKit 有什么区别?AG-UI 是协议:一套标准事件,AI 智能体把事件流式发送到用户界面。CopilotKit 是前端框架,负责渲染这些事件,提供聊天、工具调用、共享状态和人工介入等组件。CopilotKit 基于 AG-UI 构建,两者出自同一个团队。
-
应用内 AI 智能体该自研还是采用现成方案?凡是每个智能体都需要的部分,直接用现成的:聊天界面、流式传输、智能体与界面的通信协议,以及处理等待用户输入时的暂停逻辑。属于你自己产品的部分要自研:智能体调用的工具、权限、审批规则,以及引用你自己数据的出处标注。
-
fynk 助手会用我的合同来训练 AI 模型吗?不会。所有 AI 处理都在欧盟境内完成,你的数据绝不会用于训练 AI 模型。助手也只能看到和操作你本人账号权限范围内的内容。我们的安全页面列出了所有服务提供商。
-
哪些 fynk 套餐包含助手?全部套餐都包含。助手是每个 fynk 套餐的一部分,不需要单独购买 AI 附加组件。定价页面列出了各套餐详情。
试用、读代码,或者两者都来
每个 fynk 账号都能用上助手:在侧边栏的“fynk AI”下,或通过每个页面上的助手徽标进入。如果你更想用自己的 AI 工具,fynk MCP 服务器能提供同样的工具。如果你用 Vue 开发,CopilotKit for Vue 已经为你的下一个智能体准备好了。其中有一部分是我们做的,我们很想看看你会用它做出什么。
CopilotKit 在他们的博客上宣布了对 Vue 的支持。
感谢 CopilotKit 和 AG-UI 团队的审阅、修复和耐心。也感谢 Abel——他本打算写几行代码,结果写出了一个框架移植版。
请注意,我们博客上的任何内容都不应被视为法律建议。我们理解法律事务的复杂性和细微之处,尽管我们努力确保信息准确有用,但它无法替代合格法律专业人士的个性化建议。
-
我们第一个 AI 聊天哪里出了问题?
-
我们为什么转向开放协议?
-
框架不支持你的技术栈时怎么办?
-
有了编码智能体,小团队现在能承接什么?
-
应用内智能体要具备哪些条件,人们才敢把合同交给它处理?
-
哪些应该自建,哪些应该直接采用?
-
常见问题
-
试用、阅读代码,或者两者都做
分享

定期获取有见地的合同管理内容
我们尊重您的隐私。您可以随时取消订阅。
接下来
-
法务运营Claude 法律制品:画廊里有什么,合同团队能怎么用Claude 法律制品能把法律文档变成可共享的工作看板、表格和检查工具。Rezvan Golestaneh2026年10月30日•7 分钟阅读
-
合同合同价值泄漏:合同在哪个阶段漏钱,逐阶段拆解合同价值泄漏从签约前就开始了,而且 PDF 归档之后还在继续。Rezvan Golestaneh2026年10月30日•10 分钟阅读
-
洞察2027 年合同管理统计:155 项研究说明了什么合同管理存在执行不到位的问题。这些发现指出了应该关注哪里。Rezvan Golestaneh2026年10月30日•12 分钟阅读
掌控你的协议。推动业务向前。
按应有的方式运行协议:快速、清晰,按你的条款来。
没有部署烦恼
几天就能上线,不用等几个季度
没有锁定
随时完整导出
没有隐藏费用
签名功能已包含,不按信封收费