TEN Framework 入坑记

简介: TEN Framework 入坑记

TL;DR

TEN Framework 最初叫 Astra,后改为 TEN,即 Transformative Extensions Network。

我第一次见到 TEN (那时还叫 Astra)是在今年的 6 月份的极客公园 AGI Playground 大会 RTE OpenDay 的活动上。当时展区现场人声嘈杂,但对话效果已经很不错。当时我们在展示用 XSwitch 支持多模态对话,我们已经可以接入各种视频会议系统,以及各种 AI 提供商的 API,但还没有接入 TEN。

XSwitch 是一个多协议的音视频和 AI 连接器(Connector),致力于接入所有音视频和 AI 相关的平台和服务。因此,TEN 也是一个我们需要接入的框架和协议。

TEN 框架写得其实非常好,Docker 容器也很容易跑起来,但在接入过程中,我们还是遇到了一些问题,有些已经解决,有些还在解决中。在踩坑的过程中,也深入理解了这个框架,遇到一些问题,也发现了它的好。
前端的问题及优化

在官方网站上试用的时候,有时候发现前端不响应。点击 Join 按钮没有任何反应。后来发现,服务器可能在国外,首页加载看起来倒很快,但后台可能还在“懒”加载一些 JS 等内容,在加载完成前,Join 按钮是没有反应的,看起来就像是卡住了。

我们做了一些优化并提了一个 PR,在加载过程中显示“Loading ...”,并不允许点击,这样,至少用户可以理解成是页面由于等待网络等原因没有加载完成,而不是个 Bug。
Docker 相关的问题

TEN 是使用 C、Rust 和 Go 混合开发的,因此会用到 Cgo。底层组件有一些没有适配 ARM,因此只有 x86-64 镜像,这对于 Apple Silicon 的用户来说不够友好,不过,按官方文档中的指导,也可以顺利跑起来。

编译却很令人头疼。由于我使用了 OrbStack,TEN 开发人员可能都没有用过,因此在编译时有一个检查没有通过。后来几经探索,找到一个编译脚本,把里面的检查去掉,算是绕过去了。后来反馈到微信群里,TEN 的开发人员也确认了这个问题,现在已经修好了。
编译遇到的问题

TEN 提供了一键编译的脚本,但 TEN 包含了 Python、Go 等多种语言和多种依赖,在编译期间会自动下载一些依赖,有时候下载时间很长,有时候下载失败,再加上那段时间正好碰上国内无法下载 Docker 镜像的问题,总之一键编译并不能一键完成。

这也算是生活在国内程序员的日常了,如果使用这么复杂的系统,就必须具备一定的上网技能。我有一个 socks5 代理,但是有些 Python 环境不支持 socks5,我只好禁用掉代码,在开发镜像中安装了以下内容:

pip install pysocks

pip install httpx[socks]

然后,再开启 HTTPS 代理:

export HTTPS_PROXY=socks5://host.orb.internal:8888

其中,host.orb.internal:8888 是我 socks5 代理的地址。这是在 OrbStack 在 Docker 容器中访问宿主机 IP 的方法。这样,我拿着笔记本满世界乱跑时就不需要每次都修改 IP 地址之类的。

为了让 OpenAI 能用上代理,需要在 .env 中配置以下内容:

OPENAI_PROXY_URL=socks5://host.orb.internal:8888

好在编译脚本基本上是幂等的,多执行几次,总会成功。
Graph Designer 相关问题

TEN 的 Graph Designer 是一个很好的工具,可以用来设计对话流程。但最初的版本功能很弱(现在也不是很强,还是 Beta 版)。Graph Designer 连接到后台一个 property.json 文件,修改了以后刷新页面不生效。需要重启所有 Docker 容器。但我在开发过程中,重启所有 Docker 容器就意味着要重新编译安装很多东西,而这个过程很慢,又不是每次能成功。在微信群里问,开发人员支持很积极,但是没有给出有效的解决方案,直到后来我自己找到了原因。

ten_graph_designer 容器只是个前端,它连接到 astra_agents_dev 里的一个 tman 服务进程上,默认端口是 49483,由 make run-gd-server 命令启动。因此,只需要重启这个 tman 服务进程就可以了,而不需要重启整个 Docker 容器。

但事情没有那么简单,make run-gd-server是随着 Docker 容器一起启动的,kill 掉 tman 以后整个容器也会退出!所以,我只好修改了 docker-compose.yml,增加了一个entrypoint,让它启动 bash 而不是 tman。

entrypoint: ["/usr/bin/bash"]

启动 Docker 后,通过docker exec -it astra_agents_dev bash再进入容器,手工使用 make run-gd-server 启动 tman 服务进程。这样,每次修改 property.json 以后,只需要在容器中重启 tman 服务进程就可以了。

作为一个新手,在 Graph Designer 做了修改并 Save 以后,习惯性地看一看 git diff。发现 property.json 格式变化很大,无法有效知道到底是改了什么。这个如果能保证一个一致的格式就好了。好像有一个 PR 已经在跟进这个问题了。

其实这个问题也不难发现,只是我前期急于写框架,反正全面重启下又不是不能用。现在看来,“磨刀不误砍柴工”,如果早点搞定这个问题应该能多节约一点时间。
缓存优化

astra_agents_dev容器在安装各种 Python 或 Go 依赖包时,会有很多缓存到/root/.cache目录下。在docker-compose.yml中做一个持久化,映射到宿主机的.cache目录下,可以加快后续的编译速度。当然,这个要重启容器。

volumes:

  • ./:/app

  • ./.cache:/root/.cache

编译过程优化

整个编译过程基本都是靠install_deps_and_build.sh脚本完成的,它会编译所有内容。这个编译非常耗时。目前,我只开发了 Go Extension,没有改 Python,就没有必要每次都检查并下载 Python 的依赖。好在这个脚本写得非常清楚,我只是简单的把 Go 不相关的行全部注释掉了,这样编译速度就快了很多。

echo "install dependencies..."

tman install

build extensions and app

echo "build_cxx_extensions..."

build_cxx_extensions $APP_HOME

echo "build_go_app..."

build_go_app $APP_HOME

echo "install_python_requirements..."

install_python_requirements $APP_HOME

echo "post installation..."

post_install $APP_HOME

当然,如果你只是尝试在本地运行 TEN Framework,也没必要像我这样折腾,因为你一般只需要编译一次就好了。而我需要写插件。
写 Hello World 插件

按官方文档用 Go 写了个 Hello World 插件,比较顺利,但也不是一点都不需要改。用 tman 生成代码后,要修改hello_world/default_extension.go中 init 函数中的内容,有一个字符串要改成hello_world,否则会提示找不到插件。

// Register addon

ten.RegisterAddonAsExtension(

    "hello_world",

    ten.NewDefaultExtensionAddon(newDefaultExtension),

)

在使用 tman 生成插件以后,使用 git diff可以看到有一个 manifest文件有变化,但是编译完成后,变化又还原了一部分,开发人员说可能是个 Bug,但是我测试了好像也不影响运行。
一点建议

Graph Designer 虽然还是 Beta 版,但功能已经很不错了。不过,也还有一些可改进之处。

首先是它看起来很酷,但我花了很长时间才搞明白它是怎么用的。文档也不是很全,尤其是 flush 根本没有任何解释,只好去啃源代码。

Graph 看起来很酷,表示数据流的虚线也是动的,看起来就像是数据在流动。但是一旦图一复杂,就容易花眼。我感觉这个虚线应使用样条曲线(spline)而不应该使用直线,另外,也可以使用不同的颜色表示不同的数据类型。大家可以对比以下两个图看哪个更容易理解。[box.bj-yuanyang.com)
[box.lzjkjys.com)
[box.zhangyafei.com)
[box.szjinbocc.com)
[box.q345i.com)
[box.rongtianwj.com)
[box.taisheng917.com)

原图

Graphviz图

后面的图是我使用 Graphviz 生成的,我其实对 Python 并不熟,但有了 ChatGPT,我也会写 Python 代码了,我使用了如下提示词。

write a python script, convert json into graphviz digraph

graph nodes take from nodes

nodes label use html syntax

graph edge take from connections

node has ports like data and text_data, make them in a sub table, in ports at left, out ports and right

an example json follows

... 后面是简化后的 property.json 内容 ...

当然生成的代码直接编译会有错误,我修了一下,并做了很多改进,最后提了一个 PR。
我们还做了什么

我们其实研究了很多。TEN 框架包括前端和后端,在我们还没有搞明白后端的时候,我们就山寨了一个前端,然后把后端接入到了 TEN(当时还叫 Astra)官方的后端上给客户演示,薅了一把 TEN 的流量,直到有一天我们发现被限流。不过我们只是自己测试也没有对外宣传,遇到限流应该就是 TEN 的试用者本身比较多,而不是我们的锅 😂。

当然,这个方法是个秘密,我们不说。

另外,我们直接在 XSwitch 中打通了 TEN。XSwitch 是一个软交换平台,支持 SIP、H323、WebRTC 等多种协议。我们是最早跟 Agora 打通的平台。TEN 的 RTC 功能现在是由 agora_rtc 组件支持的,而且信令也不复杂,只有 start、ping、stop 三个 API。我们直接在 XSwitch 中写了一个 Lua 脚本就打通了,使用任何 PSTN 或 SIP 话机,拨打一个电话号码就可以直接跟 TEN 聊天。

最近几天的成果,我学会写插件了。我直接在 TEN 中写了一个 xswitch 插件,现在,也可以在 Graph Designer 中使用 xswitch 了。但是 TEN Store 还没有做好,我们还没有对外发布。我们也只是 Alpha 阶段,有些流程还没有调好。

在国庆放假前的一天,我改了一下 agents 框架,可以从 TEN 框架中直接启动 XSwitch 插件,甚至不需要 agora_rtc。但我不跟别人说 😂 。
再说 TEN

TEN 框架其实有三部分组成,底层叫 TEN Framework,由 C、Rust 和 Go 写成,我看了一下源代码,但还没有学会怎么编译。如果你不开发底层,好像也不需要编译。

大部分人其实不需要改 TEN Framework,我这些天主要折腾的也都是 TEN Agent,这也是第二部分,大家可以在这里面写插件。TEN 的神奇之处是你可以使用 Python、Go、C++ 等语言写插件,并通过 Graph Designer(或 JSON)把这些插件串联起来,组成一个图(Graph),然后不同语言写得插件甚至可以在同一个进程中运行!

第三部分就是上面说的 Graph Designer。日后,更多的开发者其实只需要会 Graph Designer 就好了,然后就可以组合出不同的对话流程。如果 Graph Designer 成熟了,TEN Agent 里面的插件丰富了,也许就不需要我们这些开发者了。

话说回来,TEN 框架其实写得很好,读源代码也会发现其作者功力很深。虽然现在文档不多,但还是包括了很多概念和框架设计的基本内容,对开发者也比较友好,甚至包括 tman 工具,以及如何设置 VS Code,如何 Debug 等。但也是正因为文档不多,很多东西还需要自己摸索。微信群里支持很积极,但总不能什么都问吧,哈哈。
更多期待

期待 TEN 会越来越好。另外,如何更好地组织源代码,把自己开发的 Extension 放到独立的仓库中(不管开源还是不开源),而不是跟现有的 Agent 代码混在一起,也是一个很令人期待的事情。
小结

国庆第一天没出门,还是折腾了一下 TEN,顺便写了这篇文章。

不得不说,入坑还是很有门槛的。

首先 Docker 就挡住了不少人。
其次,虽然官方提供了 Docker,但还是需要自己编译,因为有些依赖不能流畅下载的缘故,这个门槛很高。
再次,框架支持很多语言,这是个好事,但对开发者要求也很高。不过,如果看了我的书《大道至简》,应该就不怕了。
最后,TEN 还很年轻,文档不全,仅有的文档也大多是英文的。

当然,这其实都不是什么问题。很多人都说,有 AI 了,就不需要程序员了。但我做为一个会很多语言的程序员,在 RTC 这一行混了这么多年,折腾起 TEN 框架来还是花了不少时间。未来不是不需要程序员了,是未来的程序员要懂很多语言。光一个 TEN 框架就包含了 C/C++、Rust、Go、Python、Shell、Javascript 等这么多语言,如果一点都不了解的话,折腾起来还是很费劲的。这也是我写《大道至简》 的初衷——希望大家从根本上系统地了解编程开发的本质。

时间仓促,简单记录一下,希望对大家有帮助。TEN 框架是一个很有前途的框架,如果后面我有什么新发现,再跟大家分享吧。
更新

就在写完这篇文章的第二天,发生了一件大事:OpenAI 宣布了 Realtime API,以及与 Agora 的合作,Agora 股票(股票代码是 API,这个一看就很高级)应声大涨,我有点后悔没有美股的账户了。相关链接如下:

https://openai.com/index/introducing-the-realtime-api/
https://www.agora.io/en/blog/agora-and-openai-enabling-natural-real-time-conversational-ai/

不知道 TEN 框架对此有多少助力,但看起来,一切皆是因果。

TEN 团队在国庆假期里挑灯夜战,不仅合并了 5.0 分支,也实现了 OpenAI 最新的 Realtime API,这个进度,我还没有跟上。看来在接下来的几天里,我又有活干了。

相关文章
|
24天前
|
弹性计算 人工智能 架构师
阿里云携手Altair共拓云上工业仿真新机遇
2024年9月12日,「2024 Altair 技术大会杭州站」成功召开,阿里云弹性计算产品运营与生态负责人何川,与Altair中国技术总监赵阳在会上联合发布了最新的“云上CAE一体机”。
阿里云携手Altair共拓云上工业仿真新机遇
|
16天前
|
存储 关系型数据库 分布式数据库
GraphRAG:基于PolarDB+通义千问+LangChain的知识图谱+大模型最佳实践
本文介绍了如何使用PolarDB、通义千问和LangChain搭建GraphRAG系统,结合知识图谱和向量检索提升问答质量。通过实例展示了单独使用向量检索和图检索的局限性,并通过图+向量联合搜索增强了问答准确性。PolarDB支持AGE图引擎和pgvector插件,实现图数据和向量数据的统一存储与检索,提升了RAG系统的性能和效果。
|
20天前
|
机器学习/深度学习 算法 大数据
【BetterBench博士】2024 “华为杯”第二十一届中国研究生数学建模竞赛 选题分析
2024“华为杯”数学建模竞赛,对ABCDEF每个题进行详细的分析,涵盖风电场功率优化、WLAN网络吞吐量、磁性元件损耗建模、地理环境问题、高速公路应急车道启用和X射线脉冲星建模等多领域问题,解析了问题类型、专业和技能的需要。
2577 22
【BetterBench博士】2024 “华为杯”第二十一届中国研究生数学建模竞赛 选题分析
|
18天前
|
人工智能 IDE 程序员
期盼已久!通义灵码 AI 程序员开启邀测,全流程开发仅用几分钟
在云栖大会上,阿里云云原生应用平台负责人丁宇宣布,「通义灵码」完成全面升级,并正式发布 AI 程序员。
|
3天前
|
JSON 自然语言处理 数据管理
阿里云百炼产品月刊【2024年9月】
阿里云百炼产品月刊【2024年9月】,涵盖本月产品和功能发布、活动,应用实践等内容,帮助您快速了解阿里云百炼产品的最新动态。
阿里云百炼产品月刊【2024年9月】
|
2天前
|
存储 人工智能 搜索推荐
数据治理,是时候打破刻板印象了
瓴羊智能数据建设与治理产品Datapin全面升级,可演进扩展的数据架构体系为企业数据治理预留发展空间,推出敏捷版用以解决企业数据量不大但需构建数据的场景问题,基于大模型打造的DataAgent更是为企业用好数据资产提供了便利。
163 2
|
20天前
|
机器学习/深度学习 算法 数据可视化
【BetterBench博士】2024年中国研究生数学建模竞赛 C题:数据驱动下磁性元件的磁芯损耗建模 问题分析、数学模型、python 代码
2024年中国研究生数学建模竞赛C题聚焦磁性元件磁芯损耗建模。题目背景介绍了电能变换技术的发展与应用,强调磁性元件在功率变换器中的重要性。磁芯损耗受多种因素影响,现有模型难以精确预测。题目要求通过数据分析建立高精度磁芯损耗模型。具体任务包括励磁波形分类、修正斯坦麦茨方程、分析影响因素、构建预测模型及优化设计条件。涉及数据预处理、特征提取、机器学习及优化算法等技术。适合电气、材料、计算机等多个专业学生参与。
1576 16
【BetterBench博士】2024年中国研究生数学建模竞赛 C题:数据驱动下磁性元件的磁芯损耗建模 问题分析、数学模型、python 代码
|
22天前
|
编解码 JSON 自然语言处理
通义千问重磅开源Qwen2.5,性能超越Llama
击败Meta,阿里Qwen2.5再登全球开源大模型王座
977 14
|
4天前
|
Linux 虚拟化 开发者
一键将CentOs的yum源更换为国内阿里yum源
一键将CentOs的yum源更换为国内阿里yum源
221 2
|
17天前
|
人工智能 开发框架 Java
重磅发布!AI 驱动的 Java 开发框架:Spring AI Alibaba
随着生成式 AI 的快速发展,基于 AI 开发框架构建 AI 应用的诉求迅速增长,涌现出了包括 LangChain、LlamaIndex 等开发框架,但大部分框架只提供了 Python 语言的实现。但这些开发框架对于国内习惯了 Spring 开发范式的 Java 开发者而言,并非十分友好和丝滑。因此,我们基于 Spring AI 发布并快速演进 Spring AI Alibaba,通过提供一种方便的 API 抽象,帮助 Java 开发者简化 AI 应用的开发。同时,提供了完整的开源配套,包括可观测、网关、消息队列、配置中心等。
734 9