目录

graphviz

https://dreampuf.github.io/GraphvizOnline

prompt
请使用Graphviz 绘制一下流程逻辑

digraph TEN_Agent_Flow {
    // 图形设置
    rankdir=TB;
    node [shape=box, style=filled, fontname="Arial", margin="0.3,0.1"];
    edge [fontname="Arial", fontsize=10];
    
    // 节点定义
    user [label="用户", fillcolor=lightblue];
    docker [label="Docker 容器\nten_agent_dev", fillcolor=lightgrey];
    task_use [label="task use\n(构建命令)", fillcolor=lightgreen];
    task_run [label="task run\n(运行命令)", fillcolor=lightgreen];
    
    // TEN Framework 组件
    subgraph cluster_framework {
        label="TEN Framework";
        style=filled;
        color=lightgrey;
        
        build_script [label="构建脚本\ninstall_deps_and_build.sh", fillcolor=lightyellow];
        
        subgraph cluster_build_process {
            label="构建流程";
            style=filled;
            color=white;
            
            tman [label="tman install\n依赖管理", fillcolor=lightpink];
            cxx_build [label="C++ 扩展构建\nbuild_cxx_extensions()", fillcolor=lightpink];
            go_build [label="Go 应用构建\nbuild_go_app()", fillcolor=lightpink];
            python_deps [label="Python 依赖安装\ninstall_python_requirements()", fillcolor=lightpink];
        }
        
        ten_packages [label="ten_packages\n(模块化组件)", fillcolor=lightyellow];
        
        subgraph cluster_packages {
            label="组件结构";
            style=filled;
            color=white;
            
            extensions [label="extension/\n(扩展模块)", fillcolor=lightsalmon];
            system [label="system/\n(系统组件)", fillcolor=lightsalmon];
            runtime_go [label="ten_runtime_go\n(Go 运行时)", fillcolor=lightsalmon];
        }
    }
    
    // TEN Agent 应用
    subgraph cluster_agent {
        label="TEN Agent 应用";
        style=filled;
        color=lightblue;
        
        agent_server [label="Go 服务器\n(核心运行时)", fillcolor=skyblue];
        web_interface [label="Web 界面\n(Playground)", fillcolor=skyblue];
        
        subgraph cluster_features {
            label="功能模块";
            style=filled;
            color=white;
            
            voice [label="语音交互", fillcolor=lightcyan];
            vision [label="视觉识别", fillcolor=lightcyan];
            llm [label="LLM 集成", fillcolor=lightcyan];
            extensions_features [label="扩展功能", fillcolor=lightcyan];
        }
    }
    
    // 流程连接
    user -> docker [label="进入容器"];
    docker -> task_use [label="执行"];
    task_use -> build_script [label="调用"];
    
    build_script -> tman [label="1. 安装依赖"];
    tman -> cxx_build [label="2. 构建C++扩展"];
    cxx_build -> go_build [label="3. 构建Go应用"];
    go_build -> python_deps [label="4. 安装Python依赖"];
    
    system -> runtime_go [label="包含"];
    runtime_go -> go_build [label="提供构建工具"];
    
    python_deps -> ten_packages [label="安装到"];
    cxx_build -> extensions [label="构建到"];
    go_build -> agent_server [label="生成"];
    
    docker -> task_run [label="执行"];
    task_run -> agent_server [label="启动"];
    
    agent_server -> web_interface [label="提供"];
    web_interface -> user [label="访问 localhost:3000"];
    
    agent_server -> voice [label="支持"];
    agent_server -> vision [label="支持"];
    agent_server -> llm [label="集成"];
    agent_server -> extensions_features [label="启用"];
    
    extensions -> voice [label="提供功能"];
    extensions -> vision [label="提供功能"];
    extensions -> llm [label="提供功能"];
    extensions -> extensions_features [label="提供功能"];
}

TEN框架目录结构关系图

这个Graphviz图表展示了TEN框架的三个主要组成部分及其关系:

  • TENFramework(底层框架)
  • 由C、Rust 和Go 语言实现的核心运行时
  • 包含Go运行时和Python 运行时组件
  • 为TEN Agent提供基础设施
  • TEN Agent(应用层)
  • 主要目录结构包括 examples(示例代理)、scripts(构建脚本)和ten_packages
  • ten_packages 分为 extension(扩展模块)和 system(系统组件)
  • 通过 manifest.json声明依赖,通过 property.json 配置代理
  • Graph Designer(可视化编排工具)
  • 包含Playground(Web 界面)和图形编辑器
  • 用于可视化编辑和生成property.json 配置文件

图表还展示了多语言支持的特性,允许使用Python、Go 和C++ 编写扩展,这些扩展可以通过 GraphDesigner 组合成一个工作流图,并在同一进程中运行。

这个结构使得开发者可以专注于不同层次的开发:

  • 底层框架开发者可以改进TEN Framework
  • 插件开发者可以在TEN Agent中创建新的扩展
  • 应用开发者可以使用 GraphDesigner 组合现有组件创建新的代理
digraph TEN_Framework_Structure {
    // 图形设置
    rankdir=TB;
    node [shape=box, style=filled, fontname="Arial", margin="0.3,0.1"];
    edge [fontname="Arial", fontsize=10];
    
    // 主要组件节点
    TEN_Framework [label="TEN Framework\n(底层框架)", fillcolor=lightblue];
    TEN_Agent [label="TEN Agent\n(应用层)", fillcolor=lightgreen];
    Graph_Designer [label="Graph Designer\n(可视化编排工具)", fillcolor=lightyellow];
    
    // 目录结构节点
    subgraph cluster_framework {
        label="TEN Framework 目录结构";
        style=filled;
        color=aliceblue;
        
        framework_core [label="核心运行时\n(C/Rust/Go)", fillcolor=lightcyan];
        ten_runtime_go [label="ten_runtime_go\n(Go运行时)", fillcolor=lightcyan];
        ten_runtime_python [label="ten_runtime_python\n(Python运行时)", fillcolor=lightcyan];
    }
    
    subgraph cluster_agent {
        label="TEN Agent 目录结构";
        style=filled;
        color=honeydew;
        
        agents_dir [label="agents/", fillcolor=palegreen];
        examples [label="examples/\n(示例代理)", fillcolor=palegreen];
        scripts [label="scripts/\n(构建脚本)", fillcolor=palegreen];
        ten_packages [label="ten_packages/", fillcolor=palegreen];
        
        subgraph cluster_packages {
            label="ten_packages 结构";
            style=filled;
            color=white;
            
            extension [label="extension/\n(扩展模块)", fillcolor=palegreen];
            system [label="system/\n(系统组件)", fillcolor=palegreen];
        }
        
        manifest [label="manifest.json\n(依赖声明)", fillcolor=palegreen];
        property [label="property.json\n(代理配置)", fillcolor=palegreen];
    }
    
    subgraph cluster_server {
        label="服务器组件";
        style=filled;
        color=lavender;
        
        server_dir [label="server/", fillcolor=plum];
        api_server [label="API服务器\n(Go实现)", fillcolor=plum];
    }
    
    subgraph cluster_designer {
        label="Graph Designer 组件";
        style=filled;
        color=lemonchiffon;
        
        playground [label="Playground\n(Web界面)", fillcolor=khaki];
        graph_editor [label="图形编辑器", fillcolor=khaki];
    }
    
    // 关系连接
    TEN_Framework -> framework_core [label="包含"];
    TEN_Framework -> ten_runtime_go [label="包含"];
    TEN_Framework -> ten_runtime_python [label="包含"];
    
    TEN_Agent -> agents_dir [label="主目录"];
    agents_dir -> examples [label="包含"];
    agents_dir -> scripts [label="包含"];
    agents_dir -> ten_packages [label="包含"];
    agents_dir -> manifest [label="配置文件"];
    agents_dir -> property [label="配置文件"];
    
    ten_packages -> extension [label="包含"];
    ten_packages -> system [label="包含"];
    system -> ten_runtime_go [label="引用"];
    system -> ten_runtime_python [label="引用"];
    
    TEN_Agent -> server_dir [label="包含"];
    server_dir -> api_server [label="实现"];
    
    Graph_Designer -> playground [label="包含"];
    Graph_Designer -> graph_editor [label="包含"];
    
    // 组件间关系
    TEN_Framework -> TEN_Agent [label="提供基础设施"];
    TEN_Agent -> Graph_Designer [label="提供可视化界面"];
    Graph_Designer -> property [label="生成/编辑"];
    
    // 构建和运行流程
    scripts -> TEN_Framework [label="构建调用", style=dashed];
    scripts -> TEN_Agent [label="构建调用", style=dashed];
    api_server -> extension [label="加载扩展", style=dashed];
    api_server -> system [label="使用系统组件", style=dashed];
    
    // 多语言支持
    extension -> {Python_Extensions, Go_Extensions, CPP_Extensions} [style=dashed];
    Python_Extensions [label="Python扩展", fillcolor=lightpink];
    Go_Extensions [label="Go扩展", fillcolor=lightpink];
    CPP_Extensions [label="C++扩展", fillcolor=lightpink];
}

TEN Agent框架架构图解

以下是基于我们的讨论整理的几个 Graphviz 图,展示 TEN 框架的不同方面。

digraph TEN_Framework {
    rankdir=TB;
    node [shape=box, style=filled, fillcolor=lightblue, fontname="Arial"];
    edge [fontname="Arial"];
    
    subgraph cluster_framework {
        label="TEN Framework";
        style=filled;
        fillcolor=lightyellow;
        
        Server [label="HTTP Server\n(管理层)"];
        GraphDesigner [label="Graph Designer\n(可视化编辑)"];
        
        subgraph cluster_agents {
            label="Agents";
            style=filled;
            fillcolor=lightcyan;
            
            DefaultAgent [label="Default Agent"];
            CustomAgent [label="Custom Agent"];
        }
        
        subgraph cluster_extensions {
            label="Extensions";
            style=filled;
            fillcolor=lightgreen;
            
            PythonExt [label="Python Extensions"];
            GoExt [label="Go Extensions"];
            CppExt [label="C++ Extensions"];
        }
    }
    
    Client [shape=box, fillcolor=lightpink];
    
    Client -> Server [label="API 请求\n(/start, /stop, /ping)"];
    Server -> DefaultAgent [label="启动/管理"];
    Server -> CustomAgent [label="启动/管理"];
    Client -> GraphDesigner [label="设计图形"];
    GraphDesigner -> Server [label="应用配置"];
    
    DefaultAgent -> PythonExt [label="使用"];
    DefaultAgent -> GoExt [label="使用"];
    DefaultAgent -> CppExt [label="使用"];
    CustomAgent -> PythonExt [label="使用"];
}

2. 配置文件关系图

digraph Configuration_Files {
    rankdir=LR;
    node [shape=box, style=filled, fontname="Arial"];
    edge [fontname="Arial"];
    
    manifest [label="manifest.json\n(组件定义)", fillcolor=lightblue];
    property [label="property.json\n(配置参数)", fillcolor=lightgreen];
    
    subgraph cluster_extension {
        label="Extension";
        style=filled;
        fillcolor=lightyellow;
        
        ext_manifest [label="manifest.json\n(接口定义)", fillcolor=lightblue];
        ext_property [label="property.json\n(默认配置)", fillcolor=lightgreen];
    }
    
    subgraph cluster_agent {
        label="Agent";
        style=filled;
        fillcolor=lightcyan;
        
        agent_manifest [label="manifest.json\n(依赖声明)", fillcolor=lightblue];
        agent_property [label="property.json\n(图形定义)", fillcolor=lightgreen];
    }
    
    ext_manifest -> manifest [label="定义接口"];
    ext_property -> property [label="提供默认值"];
    agent_manifest -> manifest [label="声明依赖"];
    agent_property -> property [label="覆盖配置\n定义图形"];
    
    agent_property -> ext_property [label="覆盖", style=dashed];
}

3. 启动流程图

4. 扩展开发流程图

digraph Extension_Development {
    rankdir=TB;
    node [shape=box, style=filled, fillcolor=lightblue, fontname="Arial"];
    edge [fontname="Arial"];
    
    create_dir [label="创建扩展目录"];
    
    subgraph cluster_files {
        label="创建必要文件";
        style=filled;
        fillcolor=lightyellow;
        
        manifest [label="manifest.json\n(接口定义)"];
        property [label="property.json\n(默认配置)"];
        code [label="extension.py/go/cpp\n(实现代码)"];
        init [label="__init__.py\n(Python专用)"];
    }
    
    create_agent [label="创建使用扩展的Agent"];
    build [label="构建 (task build)"];
    run [label="运行 (task run)"];
    test [label="测试 (Playground)"];
    
    create_dir -> manifest;
    create_dir -> property;
    create_dir -> code;
    create_dir -> init;
    
    manifest -> create_agent;
    property -> create_agent;
    code -> create_agent;
    init -> create_agent;
    
    create_agent -> build;
    build -> run;
    run -> test;
}

digraph Data_Flow {
    rankdir=LR;
    node [shape=box, style=filled, fontname="Arial"];
    edge [fontname="Arial"];
    
    subgraph cluster_voice_assistant {
        label="Voice Assistant Graph";
        style=filled;
        fillcolor=lightyellow;
        
        agora_rtc [label="Agora RTC\n(音频通信)", fillcolor=lightpink];
        stt [label="STT\n(语音识别)", fillcolor=lightblue];
        llm [label="LLM\n(对话生成)", fillcolor=lightgreen];
        tts [label="TTS\n(语音合成)", fillcolor=lightcyan];
        tools [label="Tools\n(外部工具)", fillcolor=lightsalmon];
    }
    
    user [label="用户", shape=oval, fillcolor=white];
    
    user -> agora_rtc [label="语音输入"];
    agora_rtc -> stt [label="音频帧"];
    stt -> llm [label="文本数据"];
    llm -> tools [label="工具调用"];
    tools -> llm [label="工具结果"];
    llm -> tts [label="回复文本"];
    tts -> agora_rtc [label="合成音频"];
    agora_rtc -> user [label="语音输出"];
}

6. Server API 交互图

digraph Server_API {
    rankdir=TB;
    node [shape=box, style=filled, fillcolor=lightblue, fontname="Arial"];
    edge [fontname="Arial"];
    
    client [label="客户端应用", fillcolor=lightpink];
    
    subgraph cluster_server {
        label="HTTP Server";
        style=filled;
        fillcolor=lightyellow;
        
        start_api [label="/start\n(启动Agent)"];
        stop_api [label="/stop\n(停止Agent)"];
        ping_api [label="/ping\n(保持活跃)"];
        graphs_api [label="/graphs\n(获取可用图)"];
        token_api [label="/token/generate\n(生成令牌)"];
    }
    
    subgraph cluster_workers {
        label="Worker 进程";
        style=filled;
        fillcolor=lightcyan;
        
        worker1 [label="Worker 1\n(Channel A)"];
        worker2 [label="Worker 2\n(Channel B)"];
        worker3 [label="Worker 3\n(Channel C)"];
    }
    
    client -> start_api [label="请求启动"];
    client -> stop_api [label="请求停止"];
    client -> ping_api [label="定期ping"];
    client -> graphs_api [label="查询可用图"];
    client -> token_api [label="请求令牌"];
    
    start_api -> worker1 [label="创建进程"];
    start_api -> worker2 [label="创建进程"];
    start_api -> worker3 [label="创建进程"];
    
    stop_api -> worker1 [label="终止进程", style=dashed];
    stop_api -> worker2 [label="终止进程", style=dashed];
    stop_api -> worker3 [label="终止进程", style=dashed];
    
    ping_api -> worker1 [label="更新时间戳", style=dotted];
    ping_api -> worker2 [label="更新时间戳", style=dotted];
    ping_api -> worker3 [label="更新时间戳", style=dotted];
}

这些图表展示了 TEN 框架的不同方面,包括整体架构、配置文件关系、启动流程、扩展开发流程、数据流和 Server API 交互。它们应该能帮助您更好地理解 TEN 框架的工作原理。

前端与TEN Agent框架交互流程图

sequenceDiagram participant User as 用户 participant Frontend as 前端应用 participant RTCClient as Agora RTC 客户端 participant Server as TEN HTTP Server participant Worker as Agent Worker participant RTCService as Agora RTC 服务 Note over User,RTCService: 初始化阶段 User->>Frontend: 访问应用 Frontend->>Server: 请求 RTC 令牌 (/token/generate) Server->>Frontend: 返回令牌 Frontend->>Server: 获取可用图列表 (/graphs) Server->>Frontend: 返回图列表 (voice_assistant 等) Note over User,RTCService: 启动 Agent Frontend->>Server: 启动 Agent (/start)<br>{channel_name, graph_name: 'voice_assistant', user_uid, properties} Server->>Worker: 创建 Worker 进程 Worker->>Worker: 初始化 Agent Server->>Frontend: 返回启动结果 Note over User,RTCService: 建立 RTC 连接 Frontend->>RTCClient: 初始化 RTC 客户端 RTCClient->>RTCService: 加入频道 (使用相同 channel_name) Worker->>RTCService: Agent 加入相同频道 RTCService-->>RTCClient: 通知用户加入 RTCService-->>Worker: 通知 Agent 用户加入 Note over User,RTCService: 实时交互 User->>RTCClient: 语音输入 RTCClient->>RTCService: 发送音频数据 RTCService->>Worker: 转发音频到 Agent Worker->>Worker: 处理音频 (STT) Worker->>Worker: 生成回复 (LLM) Worker->>Worker: 合成语音 (TTS) Worker->>RTCService: 返回语音响应 RTCService->>RTCClient: 转发响应到客户端 RTCClient->>User: 播放语音响应 Note over User,RTCService: 保持连接 loop 每 30-60 秒 Frontend->>Server: 定期 Ping (/ping) Server->>Worker: 更新超时时间 end Note over User,RTCService: 结束会话 User->>Frontend: 结束会话 Frontend->>Server: 停止 Agent (/stop) Server->>Worker: 终止 Worker 进程 Worker-->>RTCService: 离开频道 Frontend->>RTCClient: 离开频道 RTCClient->>RTCService: 断开 RTC 连接

交互流程说明

初始化阶段

  1. 用户访问前端应用
  2. 前端向服务器请求 Agora RTC 令牌 (/token/generate)
  3. 服务器返回生成的令牌
  4. 前端获取可用的图列表 (/graphs)
  5. 服务器返回可用图列表,包括 "voice_assistant" 等

启动 Agent

  1. 前端请求启动 Agent (/start),指定:
    • channel_name: 通信频道名称
    • graph_name: 使用的图 (如 "voice_assistant")
    • user_uid: 用户的 RTC UID
    • properties: 可选的配置覆盖
  2. 服务器创建 Worker 进程运行 Agent
  3. 服务器返回启动结果

建立 RTC 连接

  1. 前端初始化 Agora RTC 客户端
  2. RTC 客户端加入指定频道
  3. Agent 也加入相同频道

实时交互

  1. 用户通过麦克风输入语音
  2. RTC 客户端将音频发送到 Agora 服务
  3. Agora 服务将音频转发给 Agent
  4. Agent 处理音频并返回响应
  5. 响应通过 Agora 服务转发回客户端
  6. 客户端播放 Agent 的语音响应

保持连接

  1. 前端定期调用 /ping API (通常每 30-60 秒)
  2. 服务器更新 Worker 的超时时间

结束会话

  1. 用户结束会话
  2. 前端请求停止 Agent (/stop)
  3. 服务器终止 Worker 进程
  4. 前端指示 RTC 客户端离开频道
  5. RTC 客户端断开与 Agora 服务的连接

注意事项

  1. RTC 通信:实际的语音交互不经过 HTTP Server,而是通过 Agora RTC 服务直接进行,这确保了低延迟的实时通信。
  2. 保活机制:如果前端未定期调用 /ping,Agent 会在超时后自动终止,除非在启动时设置了 timeout: -1。
  3. 配置覆盖:在 /start 请求中可以通过 properties 字段覆盖默认配置,例如更改 LLM 模型或 API 密钥。
  4. 多用户支持:每个用户会话需要使用不同的 channel_name,这样每个用户都有自己的 Agent 实例。

这个流程图展示了使用 default 配置时,前端与 TEN 框架后端的完整交互过程,包括 HTTP API 调用和 RTC 实时通信。

TEN Framework: 多语言运行时实现原理分析

TEN Framework (Ten Runtime Environment)能够让不同编程语言编写的扩展在同一进程内协同工作。通过仔细分析代码,我发现其实现了一个精巧的跨语言通信架构。

1. 核心架构设计

TEN Framework采用了典型的"核心+绑定层+语言扩展"的分层架构:

2. 跨语言通信的核心原理

通过分析代码,发现TEN Framework主要通过以下机制实现跨语言通信:

2.1 C/C++核心与FFI机制

从代码中可以看出,核心是一个C++实现的运行时环境,它通过C ABI导出接口,这些接口在extension.h和各语言的绑定文件中定义。例如:

  • C++核心定义了像ten_extension_create这样的函数
  • 各语言通过FFI(Foreign Function Interface)调用这些函数

2.2 代理模式和回调机制

核心部分代码展示了这种机制:

// core/include/ten_runtime/binding/cpp/detail/extension.h
binding_handle_t(::ten_extension_create(
    name,
    reinterpret_cast<ten_extension_on_configure_func_t>(&proxy_on_configure),
    reinterpret_cast<ten_extension_on_init_func_t>(&proxy_on_init),
    /* ... 其他回调函数 ... */
    nullptr))

这里的关键是:

  1. 每种语言的Extension类都有一个C++的代理对象
  2. 当C++核心需要调用Extension方法时,它调用代理对象,代理对象再回调到对应语言的代码
  3. 当语言扩展需要调用框架方法时,调用流程相反

2.3 指针和句柄跨边界传递

从代码中可以看到如何通过handle机制进行跨语言对象传递:

// core/src/ten_runtime/binding/go/interface/ten/extension.go
type extTester struct {
    ExtensionTester
    baseTenObject[C.uintptr_t]  // 包装C语言句柄
}
# core/src/ten_runtime/binding/python/interface/ten/extension.py
# libten_runtime_python是一个原生扩展,包装了C++对象
from libten_runtime_python import _Extension

3. 对象生命周期管理

从各语言的Extension接口可以看出,TEN Framework为所有扩展定义了统一的生命周期:

# Extension基类中的生命周期方法
def on_configure(self, ten_env: TenEnv) -> None: ...
def on_init(self, ten_env: TenEnv) -> None: ...
def on_start(self, ten_env: TenEnv) -> None: ...
def on_stop(self, ten_env: TenEnv) -> None: ...
def on_deinit(self, ten_env: TenEnv) -> None: ...

4. 数据传递与序列化

从数据传递代码可以看出核心机制:

# 在Python中访问底层缓冲区
buf = data.lock_buf()  # 获取对底层内存的直接访问
buf[:] = test_bytes    # 直接操作内存
data.unlock_buf(buf)   # 释放访问
// C++中的类似操作
auto buf = data->get_buf();
auto new_data = ten::data_t::create(data->get_name().c_str());
new_data->alloc_buf(buf.size());
auto new_buf = new_data->lock_buf();
memcpy(new_buf.data(), buf.data(), buf.size());
new_data->unlock_buf(new_buf);

5. 线程和异步处理模型

从代码中可以看出TEN Framework支持同步和异步两种扩展模式:

Python中提供了两种扩展基类:

# 同步扩展基类
class Extension(_Extension):
    def on_cmd(self, ten_env: TenEnv, cmd: Cmd) -> None: ...

# 异步扩展基类
class AsyncExtension(_Extension):
    async def on_cmd(self, ten_env: AsyncTenEnv, cmd: Cmd) -> None: ...

总结

TEN Framework通过一系列精心设计的机制实现了多语言扩展在同一进程内的协同工作:

  1. C/C++核心层: 提供统一的内存管理和核心功能
  2. FFI绑定层: 为每种语言提供原生绑定
  3. 代理和回调机制: 实现跨语言方法调用
  4. 句柄系统: 安全跨越语言边界传递对象引用
  5. 统一的对象模型: 所有语言使用相同的消息和数据类型抽象
  6. 统一的生命周期: 各语言扩展遵循相同的初始化和运行规则

这种架构使开发者能够用自己熟悉的语言编写扩展,同时享受统一框架带来的互操作性优势。