本地多工具智能 Agent 与语音交互系统(实训 B 方向)

本项目使用 Python 3.10 实现一个完整的本地智能 Agent 系统。系统以本地 Qwen3.5-4B 为决策核心,将 Agent 总控、Tools Schema、八类本地 Skill、长期记忆、KV Cache、音频预处理、Faster-Whisper 语音识别和 CosyVoice2 语音合成串联为统一工作流。用户可以输入文本或麦克风语音,Agent 会自主规划并调用工具,最终返回文字回答,也可以通过独立 CosyVoice 子进程生成语音。

⚠️ 使用前必须按实际电脑与服务器修改配置

仓库中的绝对路径、SSH 地址和端口均为团队开发环境示例,不能直接照搬。运行前必须检查 agent/configs/model.yaml、agent/configs/tts.yaml 和 agent/configs/voice_chat.yaml:将模型、tokenizer、CosyVoice Python/仓库/模型/参考音频改为当前电脑或服务器的实际路径;将 connection.host 改为本人可访问的 用户名@服务器地址,将 connection.port 改为目标服务器实际开放的 SSH 端口,并同步修改 connection.remote_root、connection.python 和 connection.template。详细字段见“1.3 首次运行前必须检查的私有路径”。

完整任务的数据流如下:

文本 / 麦克风音频
  → 音频预处理与 ASR(仅音频输入)
  → 加载全局记忆和会话记忆
  → Qwen3.5-4B 规划任务
  → B3 校验并调用 B2 Skills
  → 工具结果返回模型继续推理
  → 生成最终回答
  → 保存消息、轨迹、Memory 和报告
  → CosyVoice2 子进程合成语音(按需启用)

模块边界如下:

模块 入口文件 职责
B1 code/b1_agent_runtime.py Agent 总控、消息管理、循环控制和产物汇总。
B2 code/b2_run_skill.py 独立运行五个基础 Skill。
B3 code/b3_tool_layer.py 生成 tools schema,校验并执行 tool calls。
B4 code/b4_local_agent_llm.py 使用 mock 或本地 LLM 生成标准 AIMessage,不执行工具。
B5 code/b5_memory.py 查找、截断、保存 memory 文档并维护索引。
完整演示 code/run_full_demo.py 调用 B1 跑通完整 Agent,并生成汇总报告。
语音服务端 code/voice_chat_server.py 接收音频、调用 ASR 和 Agent,并维护多轮会话。
Windows 语音客户端 code/voice_chat_windows_client.py 麦克风录音、SSH 通信、本地/远程 TTS 和扬声器播放。
TTS Worker skills/text_to_speech.py、skills/tts_worker.py 从 Agent 环境启动独立 CosyVoice 子进程并生成 WAV。

B4的mock模式不真实加载、运行模型,作为无 GPU、无模型或模块联调时的调试模式。prompt_json模式则加载本地模型真实运行。

1. 环境准备

Agent 与 CosyVoice 建议使用两个独立的 Conda 环境。Agent 环境负责本地模型、工具调用、Memory 和语音识别;CosyVoice 环境只负责 TTS。两套环境分离可以避免 PyTorch、Transformers、音频库等依赖版本互相冲突。

1.1 Agent 环境

在项目根目录执行:

conda create -n agent python=3.10 -y
conda activate agent
pip install -r agent/requirements.txt

本项目默认使用 Qwen3.5-4B。agent/configs/model.yaml 中提供的是团队服务器路径,其他使用者必须将 model.model_name_or_path 和 model.tokenizer_name_or_path 改为自己机器上的模型目录。

1.2 独立 CosyVoice TTS 环境

本项目采用子进程方式运行本地 TTS:Agent 环境中的 agent/skills/text_to_speech.py 不直接导入 CosyVoice,而是读取 agent/configs/tts.yaml,使用 runtime.python_executable 指定的 CosyVoice Python 启动 agent/skills/tts_worker.py。因此,仅安装 agent/requirements.txt 不能运行 TTS,还需要单独准备 CosyVoice 环境。

conda create -n cosyvoice python=3.10 -y
conda activate cosyvoice
pip install -r CosyVoice/requirements.txt

Linux 如果遇到 SoX 依赖问题,还需要安装系统库:

# Ubuntu / Debian
sudo apt-get install sox libsox-dev

# CentOS
sudo yum install sox sox-devel

安装后,将 agent/configs/tts.yaml 中的 Python 路径改成该环境的真实解释器:

runtime:
  # Windows 示例
  python_executable: "C:/Users/<你的用户名>/anaconda3/envs/cosyvoice/python.exe"

  # Linux 示例:使用时保留其中一项即可
  # python_executable: "/home/<你的用户名>/miniconda3/envs/cosyvoice/bin/python"

还需要确认 voice.cosyvoice_repo、voice.model_dir 和各音色的 prompt_wav 指向真实存在的 CosyVoice 代码、模型及参考音频。当前仓库已经包含 CosyVoice/ 和 CosyVoice2-0.5B/,如果目录结构不变,可以继续使用配置中的相对路径。

1.3 首次运行前必须检查的私有路径

仓库配置保留了团队开发机器和服务器的示例路径,不能直接照搬到其他电脑。至少检查以下字段:

配置文件 字段 当前内容的性质 应修改为
agent/configs/model.yaml model_name_or_path、tokenizer_name_or_path 团队服务器绝对路径 本机 Qwen3.5-4B 模型目录
agent/configs/tts.yaml runtime.python_executable 团队成员 Windows Conda 路径 本机 CosyVoice 环境的 Python
agent/configs/tts.yaml cosyvoice_repo、model_dir、prompt_wav 项目相对路径 若目录被移动,改为实际路径
agent/configs/voice_chat.yaml connection.host、port 团队 SSH 服务器地址和端口 自己可访问的服务器账号、地址和端口
agent/configs/voice_chat.yaml connection.remote_root 团队服务器项目路径 服务器上的项目根目录
agent/configs/voice_chat.yaml connection.python 团队服务器 Agent 解释器 服务器 Agent 环境的 Python
agent/configs/voice_chat.yaml connection.template 团队项目中的运行模板路径 远程项目内实际存在的 runtime JSON 路径
agent/configs/voice_chat.yaml audio.sample_rate、TTS 与 conversation 配置 团队演示参数 根据本机音频设备、TTS 部署位置和会话需求调整

agent/configs/voice_chat.yaml 中的 IP、用户名、SSH 端口和远程目录均属于部署示例。运行语音客户端之前必须替换,否则客户端会尝试连接团队原服务器,或因端口、目录和解释器不匹配而启动失败。

演示命令均从 agent/code 目录执行:

cd agent/code

1.4 整体系统运行方法

以下是团队项目最常用的完整运行入口。B2–B5 的独立命令主要用于模块调试,首次使用建议先按本节跑通整体流程。

方式一:完整文本 Agent Demo

确认 Qwen 模型路径和配置后,从 agent/code 目录执行:

python run_full_demo.py \
  --input ../data/runtime_input_4.json \
  --tools_config ../configs/tools.yaml \
  --memory_config ../configs/memory.yaml \
  --model_config ../configs/model.yaml \
  --llm_mode prompt_json \
  --outdir ../outputs/full_demo

runtime_input_4.json 会让真实模型选择 table_analyzer 分析示例 CSV。一次完整任务依次经过 B1 Runtime、B5 Memory、B4 本地模型、B3 Tool Layer 和 B2 Skill,最终在 agent/outputs/full_demo/ 生成回答、消息流、工具结果、执行轨迹和汇总报告。

可以替换 --input 运行其他整体任务:

Runtime 文件 整体任务
runtime_input.json 读取本地文档并总结
runtime_input_2.json 调用安全计算工具
runtime_input_3.json 检索本地资料
runtime_input_4.json 分析 CSV 表格
runtime_input_5.json 格式转换并生成文件
runtime_input_audio.json 音频预处理 → ASR → Agent → 最终回答
runtime_input_tts.json Agent 完成任务后调用 CosyVoice2 生成 WAV

若只想检查编排流程而不加载 GPU 模型,可临时使用 --llm_mode mock;正式演示应使用 prompt_json。

方式二:完整语音对话

语音模式通常采用“Windows 客户端 + GPU 服务器 Agent”的部署方式。先完成以下检查:

  1. 修改 voice_chat.yaml 中的 SSH 地址、端口、远程项目目录和远程 Agent Python;
  2. 确认远程服务器可以运行 Qwen 和 Faster-Whisper;
  3. 本地 TTS 模式下,确认 tts.yaml 指向本机 CosyVoice Python、代码和模型;
  4. 在 voice_chat.yaml 的 tts.voice 中选择音色:default 或 funingna;
  5. 根据需要选择 tts.mode、tts.stream_mode 和 conversation.mode。

随后在项目根目录的 Windows PowerShell 中执行:

python .\agent\code\voice_chat_windows_client.py --config .\agent\configs\voice_chat.yaml

客户端会自动完成:麦克风录音 → SSH 发送音频 → 服务器预处理与识别 → Agent 调用工具并回答 → 本地或远程 CosyVoice 合成 → 扬声器播放。

常用的临时模式切换示例:

# 本地流式合成,使用 funingna 音色,连续多轮对话
python .\agent\code\voice_chat_windows_client.py `
  --config .\agent\configs\voice_chat.yaml `
  --tts-mode local `
  --tts-stream-mode stream `
  --tts-voice funingna `
  --conversation-mode append

# 切换为 default 音色和整段合成
python .\agent\code\voice_chat_windows_client.py `
  --config .\agent\configs\voice_chat.yaml `
  --tts-mode local `
  --tts-stream-mode full `
  --tts-voice default

运行成功判断

文本完整 Demo 成功时,应满足:

  • 进程退出码为 0;
  • outputs/full_demo/demo_report.md 中状态为 success;
  • messages.json 包含 system → user → assistant → tool → assistant 消息链;
  • tool_messages.json 中目标工具状态为 success;
  • final_answer.md 包含最终回答;
  • 启用 TTS 时输出目录中存在可播放的 WAV 文件。

语音模式成功时,终端会先返回识别文本和 Agent 回答;启用 TTS 后还会显示音频块进度及实际使用的 voice ID,并通过扬声器播放。

2. 公共数据格式

2.1 SkillResult

B2 和 B3 使用以下 JSON 对象记录一次 Skill 执行:

{
  "skill_name": "calculator",
  "status": "success",
  "input": {"expression": "23 * 17 + 9"},
  "output": {"result": 400},
  "error": null,
  "latency_ms": 0.5
}

失败时 status 为 error、output 为 null,error 包含异常类型和错误信息。

2.2 AIMessage

工具调用型 AIMessage:

{
  "role": "assistant",
  "content": "",
  "tool_calls": [
    {
      "id": "call_001",
      "name": "file_reader",
      "args": {"path": "docs/agent_intro.txt", "max_chars": 2000}
    }
  ]
}

最终回答型 AIMessage 的 content 非空,tool_calls 为空数组。

2.3 ToolMessage

{
  "role": "tool",
  "tool_call_id": "call_001",
  "name": "file_reader",
  "content": "{\"skill_name\":\"file_reader\",...}",
  "status": "success"
}

content 是序列化后的 SkillResult JSON 字符串;tool_call_id 用于关联前面的 AIMessage tool call。

3. B2:Skill 独立演示

入口:code/b2_run_skill.py

3.1 通用命令行输入

参数 说明
--skill Skill 名称:calculator、file_reader、local_file_search、table_analyzer 或 format_converter。
--input 对应 Skill 的 JSON 输入文件。顶层必须是 JSON 对象。
--outdir B2 输出目录。
--data_root 可选的数据根目录;未提供时使用项目的 data/。

3.2 每个 Skill 的输入文件

Skill 正常输入文件 关键输入字段 异常输入样例
calculator data/tool_inputs/tool_input_calculator.json expression:数学表达式字符串。 tool_input_calculator_error.json
file_reader data/tool_inputs/tool_input_file_reader.json path:相对 data/ 的 txt/md 路径;max_chars:最大返回字符数。 tool_input_file_reader_error.json
local_file_search data/tool_inputs/tool_input_file_search.json query、root_dir、file_types、top_k。 tool_input_file_search_error.json
table_analyzer data/tool_inputs/tool_input_table_analyzer.json path:CSV/TSV 路径;max_rows_preview;describe。 tool_input_table_analyzer_error.json
format_converter data/tool_inputs/tool_input_format_converter.json text;target_format:markdown 或 json;可选 output_filename。 tool_input_format_converter_error.json

文件类 Skill 的相对路径以 data/ 为根。例如 docs/agent_intro.txt 实际对应 data/docs/agent_intro.txt。

3.3 演示命令

python b2_run_skill.py --skill calculator --input ../data/tool_inputs/tool_input_calculator.json --outdir ../outputs/B2_skills
python b2_run_skill.py --skill file_reader --input ../data/tool_inputs/tool_input_file_reader.json --outdir ../outputs/B2_skills
python b2_run_skill.py --skill local_file_search --input ../data/tool_inputs/tool_input_file_search.json --outdir ../outputs/B2_skills
python b2_run_skill.py --skill table_analyzer --input ../data/tool_inputs/tool_input_table_analyzer.json --outdir ../outputs/B2_skills
python b2_run_skill.py --skill format_converter --input ../data/tool_inputs/tool_input_format_converter.json --outdir ../outputs/B2_skills

3.4 B2 输出

输出文件 格式 说明
outputs/B2_skills/calculator_result.json JSON 对象(SkillResult) calculator 最近一次运行的输入、结果或错误、耗时。
outputs/B2_skills/file_reader_result.json JSON 对象(SkillResult) file_reader 最近一次运行结果;业务输出包含内容、字符数、来源和截断标志。
outputs/B2_skills/local_file_search_result.json JSON 对象(SkillResult) 文件搜索结果;每项包含路径、匹配分数和命中片段。
outputs/B2_skills/table_analyzer_result.json JSON 对象(SkillResult) 表格行列数、列名、预览和数值列统计。
outputs/B2_skills/format_converter_result.json JSON 对象(SkillResult) 转换后的 Markdown 或 JSON 文本,以及生成文件路径。
outputs/B2_skills/skill_run_log.jsonl JSONL B2 运行历史;每行记录时间、Skill、状态、结果路径和耗时。

同一个 Skill 再次运行时会覆盖对应的 *_result.json;日志采用追加写入。异常样例被正常捕获并写入 error SkillResult,CLI 仍返回 0。

4. B3:Tools Schema 与工具执行

入口:code/b3_tool_layer.py

4.1 输入文件

输入文件 说明
configs/tools.yaml 定义 toolsets、每个工具的 Python 模块/函数、描述、输入参数、必填参数、返回说明和 data_root。
data/messages/ai_message_with_tool_calls.json 工具执示演示的输入,正常file_reader调用的样例,包含标准 AIMessage 及其 tool_calls。
data/messages/b3_tool_call_format_converter_valid.json 正常 format_converter 调用样例,验证 B3 注入 output_dir 并生成文件。
data/messages/b3_tool_call_unknown_tool.json 未知工具错误样例。
data/messages/b3_tool_call_missing_required.json 缺少必填参数错误样例。

B3 会根据 Skill 函数签名自动注入 data_root 和 output_dir;前者用于读取文件类Skill定位输入文件夹data/,后者用于format_converter输出生成文件。

4.2 演示命令

生成tools_schema:

python b3_tool_layer.py --tools_config ../configs/tools.yaml --toolset basic_tools --export_schema --outdir ../outputs/B3_tools

执行tool_calls:

python b3_tool_layer.py --tools_config ../configs/tools.yaml --toolset basic_tools --tool_calls ../data/messages/ai_message_with_tool_calls.json --execute --outdir ../outputs/B3_tools

基础样例:

python b3_tool_layer.py --tools_config ../configs/tools.yaml --toolset basic_tools --tool_calls ../data/messages/b3_tool_call_format_converter_valid.json --execute --outdir ../outputs/B3_tools/format_converter_valid
python b3_tool_layer.py --tools_config ../configs/tools.yaml --toolset basic_tools --tool_calls ../data/messages/b3_tool_call_unknown_tool.json --execute --outdir ../outputs/B3_tools/unknown_tool
python b3_tool_layer.py --tools_config ../configs/tools.yaml --toolset basic_tools --tool_calls ../data/messages/b3_tool_call_missing_required.json --execute --outdir ../outputs/B3_tools/missing_required

错误样例不会让 CLI 崩溃;错误会写入 tool_messages.json 和 tool_call_log.jsonl 中的 status=error SkillResult。

4.3 B3 输出

输出文件 格式 说明
outputs/B3_tools/tools_schema.json JSON 数组 当前 OpenAI 风格的函数工具说明schema;x-returns 描述工具返回值。
outputs/B3_tools/tool_schema_report.json JSON 对象 schema 导出报告,包含 toolset、工具数量和工具名称列表。
outputs/B3_tools/tool_messages.json JSON 数组 本次执行生成的 ToolMessage 列表。
outputs/B3_tools/tool_call_log.jsonl JSONL 每个 tool call 的完整执行记录,含未转义 SkillResult、状态、参数和耗时。

schema/report/tool messages 会被最近一次运行覆盖;tool-call 日志追加写入。

5. B5:Memory 查找与保存

入口:code/b5_memory.py

5.1 输入文件

输入文件 说明
configs/memory.yaml 记忆根目录、全局/对话目录、索引路径和最大注入字符数。
memory/memory_index.json memory_id → 元数据 的索引,记录类型、标题、摘要、路径和时间。
memory/global/*.md 全局记忆文档。
memory/conversations/*.md 对话记忆文档。
data/memory_inputs/memory_save_input.json 保存对话类型记忆的样例,包含 conversation ID、保存类型及三个来源文件路径。
data/memory_inputs/memory_save_global_input.json 保存全局类型记忆的样例,会写入项目正式记忆目录 memory/global/ 和 memory/memory_index.json。
data/memory_inputs/sample_messages.json 演示保存记忆时使用的消息数组。
data/memory_inputs/sample_trace.json 演示保存记忆时使用的 trace 对象。
data/memory_inputs/sample_final_answer.md 演示保存记忆时使用的最终回答。
configs/memory_small_limit.yaml 复用当前 memory/,仅降低 max_memory_chars 用于截断演示。

演示B5的查找模式时,直接通过命令行参数传入。memory_save_input.json 中的三个来源路径相对于该 JSON 文件所在目录解析,不依赖 B1 输出。

5.2 演示命令

查找记忆:

python b5_memory.py --config ../configs/memory.yaml --select_memory_ids mem_conversation_conv_000 --use_global_memory true --query "Agent 系统如何调用工具?" --outdir ../outputs/B5_memory
python b5_memory.py --config ../configs/memory.yaml --select_memory_ids mem_missing_001 --use_global_memory false --query "验证缺失 memory id 的错误记录。" --outdir ../outputs/B5_memory/missing_id
python b5_memory.py --config ../configs/memory_small_limit.yaml --select_memory_ids mem_course_001 --use_global_memory false --query "验证 max_memory_chars 截断。" --outdir ../outputs/B5_memory/truncate

保存对话记忆

python b5_memory.py --config ../configs/memory.yaml --save_type conversation --save_input_path ../data/memory_inputs/memory_save_input.json --outdir ../outputs/B5_memory
python b5_memory.py --config ../configs/memory.yaml --save_type global --save_input_path ../data/memory_inputs/memory_save_global_input.json --outdir ../outputs/B5_memory/save_global

B5 保存命令会更新项目正式记忆目录:生成或覆盖 memory/conversations/*.md / memory/global/*.md,并新增或更新 memory/memory_index.json。memory_save_global_input.json 使用唯一 conversation_id=demo_global_memory_001,避免覆盖已有示例。

5.3 B5 输出

输出文件 格式 说明
outputs/B5_memory/selected_memory.json JSON 对象 本次选中的记忆内容、字符统计、截断标志和缺失 ID 错误。
outputs/B5_memory/memory_log.jsonl JSONL 记忆查找与保存历史。
outputs/B5_memory/saved_memory.json JSON 对象 已保存记忆的 ID、类型、标题、摘要、文档路径、来源路径和时间。
memory/conversations/conv_sample_001.md Markdown 独立保存命令生成的对话记忆文档,内含最终回答、messages 和 trace。
memory/global/demo_global_memory_001.md Markdown 全局保存样例生成的全局记忆文档。
memory/memory_index.json JSON 对象 保存后新增或更新对应记忆元数据。

selected_memory.json 和 saved_memory.json 会覆盖;memory_log.jsonl 追加;索引和 Markdown 记忆文档会新增或更新。

6. B4:真实调用模型 / Mock 调试决策

入口:code/b4_local_agent_llm.py

B4 只生成 AIMessage,不执行工具。

6.1 输入文件

输入文件 说明
configs/model.yaml 统一真实模型配置:服务器本地 Qwen3.5-4B、Transformers、bf16、prompt_json。
data/messages/messages_no_tool.json 第一阶段独立运行输入,只含 system/user,真实模型应生成 tool call。
data/messages/messages_with_tool.json 第二阶段独立运行输入,已含 ToolMessage,真实模型应生成最终回答。
data/messages/messages_with_error_tool.json 已含失败 ToolMessage,验证模型直接说明失败并保持 tool_calls=[]。
data/messages/tools_schema_basic.json B4个人演示使用的预设tools_schema工具说明,不依赖B3的预先运行。

6.2 演示命令

真实加载调用模型: B4 第一阶段,生成 tool_call:

python b4_local_agent_llm.py --model_config ../configs/model.yaml --messages ../data/messages/messages_no_tool.json --tools_schema ../data/messages/tools_schema_basic.json --mode prompt_json --outdir ../outputs/B4_llm/no_tool_real

B4 第二阶段,生成 final_answer:

python b4_local_agent_llm.py --model_config ../configs/model.yaml --messages ../data/messages/messages_with_tool.json --tools_schema ../data/messages/tools_schema_basic.json --mode prompt_json --outdir ../outputs/B4_llm/with_tool_real

B4处理工具调用失败的ToolMessage结果

python b4_local_agent_llm.py --model_config ../configs/model.yaml --messages ../data/messages/messages_with_error_tool.json --tools_schema ../data/messages/tools_schema_basic.json --mode prompt_json --outdir ../outputs/B4_llm/error_tool_real

mock调试模式:

python b4_local_agent_llm.py --model_config ../configs/model.yaml --messages ../data/messages/messages_no_tool.json --tools_schema ../data/messages/tools_schema_basic.json --mode mock --outdir ../outputs/B4_llm
python b4_local_agent_llm.py --model_config ../configs/model.yaml --messages ../data/messages/messages_with_tool.json --tools_schema ../data/messages/tools_schema_basic.json --mode mock --outdir ../outputs/B4_llm

mock 不加载模型、不占用显存,适合无 GPU、无本地模型或其他模块同学联调。

6.3 B4 输出

输出文件 格式 说明
outputs/B4_llm/<case>/raw_model_output.json JSON 对象 原始生成文本、解析候选、模式、backend、状态、错误和生成时间。若status为 error,说明模型输出未能解析成合法 AIMessagemock。mock模式也会生成该记录。
outputs/B4_llm/<case>/ai_message.json JSON 对象(AIMessage) 规范化后的工具调用或最终回答。
outputs/B4_llm/<case>/llm_run_log.jsonl JSONL B4 独立运行历史及产物路径。

mock调试的演示命令共用 ../outputs/B4_llm,因此第二条会覆盖第一条的 raw_model_output.json 和 ai_message.json,但日志会追加。

7. B1:Agent Runtime

入口:code/b1_agent_runtime.py

B1 支持两种明确的执行模式:fixture 用于完全隔离的个人演示,直接消费预设 memory、tools schema、AIMessage 和 ToolMessage;integrated 用于全系统演示,只通过 B3、B4、B5 的公开函数进行编排。

7.1 直接输入文件

个人演示 fixture 模式

输入文件 说明
data/b1_fixtures/b1_fixture_input.json B1 个人演示入口,设置 execution_mode=fixture 并引用全部预设响应。
data/b1_fixtures/preset_memory.json 模拟 B5 返回的 selected memory。
data/b1_fixtures/preset_ai_messages.json 模拟 B4 依次返回的工具调用 AIMessage 和最终回答 AIMessage。
data/b1_fixtures/preset_tool_messages.json 按 tool_call_id 模拟 B3 返回的 ToolMessage。
data/messages/tools_schema_basic.json 模拟 B3 返回的固定 tools schema。

全系统演示 integrated 模式

输入文件 说明
data/runtime_input.json file_reader 主线任务,读取 docs/agent_intro.txt 并总结三条中文要点。
data/runtime_input_0.json 无工具倾向任务,验证模型直接回答。
data/runtime_input_2.json calculator 任务。
data/runtime_input_3.json local_file_search 任务。
data/runtime_input_4.json table_analyzer 任务。
data/runtime_input_5.json format_converter 任务。
configs/tools.yaml 传给 B3,确定可用工具及数据根目录。
configs/memory.yaml 传给 B5,确定 memory 路径和长度上限。
configs/model.yaml 统一真实模型配置。

7.2 间接读取文件

文件 读取原因
prompts/local_tool_agent.txt fixture 和 integrated 输入指定的 SystemMessage 模板。
memory/memory_index.json、memory/global/*.md 仅 integrated 模式读取;B5 查找并返回 memory 上下文。
data/docs/agent_intro.txt integrated file_reader 流程实际读取;fixture 模式使用预设 ToolMessage。

7.3 演示命令

个人演示 fixture 模式:

python b1_agent_runtime.py --input ../data/b1_fixtures/b1_fixture_input.json --outdir ../outputs/B1_fixture

该命令不会调用 B2–B5。

全系统 integrated 调试模式:

python b1_agent_runtime.py --input ../data/runtime_input.json --tools_config ../configs/tools.yaml --memory_config ../configs/memory.yaml --model_config ../configs/model.yaml --llm_mode mock --outdir ../outputs/B1_runtime

该命令以 B1 为入口真实调用 B3、B4、B5,但 LLM 使用mock;正式全系统演示推荐使用下一节的真实模型 full demo,或将'--llm_mode mock'改为'--llm_mode prompt_json'。

7.4 B1 输出

个人演示 fixture 模式

输出文件 格式 说明
outputs/B1_fixture/messages.json JSON 数组 B1 根据预设响应维护出的完整消息序列,顶层固定为数组。
outputs/B1_fixture/trace.json JSON 对象 B1 的分支判断、消息追加、工具轮次和最终状态。
outputs/B1_fixture/final_answer.md Markdown 从预设最终 AIMessage 提取的最终回答。

fixture模式只生成以上三个文件,不生成 runtime log、memory文档或其他模块的产物。

全系统演示 integrated 模式

输出文件 格式 说明
outputs/B1_runtime/messages.json JSON 数组 完整消息序列,顶层固定为数组。
outputs/B1_runtime/trace.json JSON 对象 运行状态、工具轮次、LLM 次数、每轮 AI/ToolMessage、memory 保存状态和错误。
outputs/B1_runtime/final_answer.md Markdown 最终给用户的回答。
outputs/B1_runtime/selected_memory.json JSON 对象 B1 调用 B5 后保存的 memory 选择结果。
outputs/B1_runtime/tools_schema.json JSON 数组 B1 调用 B3 后保存的当前工具 schema。
outputs/B1_runtime/tool_schema_report.json JSON 对象 当前 toolset 的 schema 摘要。
outputs/B1_runtime/tool_messages.json JSON 数组 本次 Agent 运行累计产生的 ToolMessage。
outputs/B1_runtime/tool_call_log.jsonl JSONL B3 工具执行明细。
outputs/B1_runtime/saved_memory.json JSON 对象 B5 保存本轮对话后的结果。
outputs/B1_runtime/memory_log.jsonl JSONL B1 运行期间的 memory 查找和保存记录。
outputs/B1_runtime/runtime_log.jsonl JSONL B1 每次完整任务的状态、模式、轮次、调用数和总耗时。
outputs/B1_runtime/llm_calls/llm_call_NNN_raw_model_output.json JSON 对象 第 N 次 B4 调用的原始输出记录。
outputs/B1_runtime/llm_calls/llm_call_NNN_ai_message.json JSON 对象 第 N 次 B4 调用生成的标准 AIMessage。
outputs/B1_runtime/llm_calls/llm_run_log.jsonl JSONL 本次 B1 运行内所有 B4 调用的日志。
memory/conversations/conv_001.md Markdown B1 按 save_memory=conversation 保存的对话 memory。
memory/memory_index.json JSON 对象 B1 保存 memory 后更新的索引。

8. 完整一键演示

入口:code/run_full_demo.py

8.1 输入文件

输入与 B1 相同:

  • data/runtime_input.json
  • configs/tools.yaml
  • configs/memory.yaml
  • configs/model.yaml
  • 以上配置间接引用的 prompt、memory 和演示文档

8.2 命令

python run_full_demo.py --input ../data/runtime_input.json --tools_config ../configs/tools.yaml --memory_config ../configs/memory.yaml --model_config ../configs/model.yaml --llm_mode prompt_json --outdir ../outputs/full_demo

该正式命令会按 runtime_input.json 中的 save_memory=conversation 更新 memory/conversations/conv_001.md 和 memory/memory_index.json。重复演示前请确认是否接受覆盖该 conversation memory。

8.3 输出

run_full_demo.py 使用 outputs/full_demo 作为 B1 integrated 模式的 outdir,因此会生成 integrated 模式的完整 artifacts,并额外生成:

输出文件 格式 说明
outputs/full_demo/demo_report.md Markdown 汇总 conversation、运行状态、消息流、工具轮次、LLM 次数、memory 数量、工具数量、最终回答和文件清单。

典型成功演示的 messages.json 角色顺序为:

system → user → assistant(tool_calls) → tool → assistant(final)

8.4 本地 TTS 与语音交互配置

TTS 子进程运行方式

调用 text_to_speech 时,Agent 会将请求写入临时 JSON,再用 CosyVoice 环境的 Python 启动 TTS Worker。agent/configs/tts.yaml 中:

  • persistent_worker: false:每次合成启动一次独立子进程,结束后释放模型;占用更容易回收,但每次都要重新加载模型。
  • persistent_worker: true:复用常驻子进程和已加载模型,适合连续对话,后续语音生成更快。
  • load_jit、fp16:控制 CosyVoice 加速和精度选项,需结合运行设备支持情况设置。
  • min_chunk_chars、max_chunk_chars、hard_max_chunk_chars:控制流式 TTS 的文本切块长度。
  • inter_chunk_silence_sec:控制合并语音块之间的静音时长。

也可以临时使用环境变量覆盖主要路径,而不修改 YAML:

$env:COSYVOICE_PYTHON="C:\path\to\envs\cosyvoice\python.exe"
$env:COSYVOICE_REPO="C:\path\to\assignment_B\CosyVoice"
$env:COSYVOICE_MODEL="C:\path\to\assignment_B\CosyVoice2-0.5B"
$env:COSYVOICE_PROMPT_WAV="C:\path\to\prompt.wav"

音色切换

项目内置 default 和 funingna 两个音色配置,定义在 agent/configs/tts.yaml 的 voice.voices 下。每个音色由参考音频 prompt_wav 和对应文本 prompt_text 组成,二者应与实际音频内容一致。

修改语音客户端默认音色:

# agent/configs/voice_chat.yaml
tts:
  voice: "default"   # 可改为 funingna

也可以在启动时临时覆盖:

python .\agent\code\voice_chat_windows_client.py --config .\agent\configs\voice_chat.yaml --tts-voice default

在 Runtime JSON 中启用最终回答 TTS 时,可通过 tts_voice 选择音色:

{
  "enable_tts": true,
  "tts_voice": "funingna"
}

新增音色时,在 agent/configs/tts.yaml 的 voice.voices 下增加新的 ID,并配置匹配的 prompt_wav 与 prompt_text,随后把 tts_voice 或 tts.voice 改为该 ID。

TTS 和会话模式切换

agent/configs/voice_chat.yaml 支持以下模式:

字段 可选值 说明
tts.mode local 在 Windows 本地通过独立 CosyVoice 子进程合成并播放;当前项目默认模式
tts.mode remote 在远程服务器合成,再将音频结果传回客户端
tts.mode none 关闭语音合成,只显示识别文本和回答
tts.stream_mode stream 回答按文本块合成,生成一块就播放一块
tts.stream_mode full 完整回答合成为一个 WAV 后再播放
tts.language auto、zh、en 自动判断、中文零样本或英文跨语言合成
conversation.mode append 同一服务进程持续追加消息,适合多轮对话与 KV Cache 复用
conversation.mode restart 每轮重新执行一次独立 Agent Runtime,通过已保存 Memory 衔接上下文

这些设置也可以通过命令行覆盖,无需修改配置文件:

# 本地流式 TTS,使用 funingna 音色,并保留连续对话上下文
python .\agent\code\voice_chat_windows_client.py `
  --config .\agent\configs\voice_chat.yaml `
  --tts-mode local `
  --tts-stream-mode stream `
  --tts-language auto `
  --tts-voice funingna `
  --conversation-mode append

# 关闭 TTS
python .\agent\code\voice_chat_windows_client.py `
  --config .\agent\configs\voice_chat.yaml `
  --tts-mode none

如不想修改 tts.yaml,语音客户端还支持 --local-tts-python、--local-cosyvoice-repo、--local-tts-model、--local-prompt-wav 和 --local-prompt-text,可在启动时覆盖本地 TTS 的环境、模型和参考音频路径。

单独验证本地流式 TTS

建议在运行完整语音对话前先验证 CosyVoice 子进程:

python .\agent\code\stream_tts_demo.py `
  --text "你好,这是本地语音合成测试。" `
  --language zh `
  --tts-voice default `
  --cosyvoice-python "C:\path\to\envs\cosyvoice\python.exe" `
  --cosyvoice-repo ".\CosyVoice" `
  --model-dir ".\CosyVoice2-0.5B"

终端应逐块显示 TTS 事件并播放语音;加入 --no-play 可以只生成和检查音频,不调用扬声器。

9. CLI 退出码

退出码 含义
0 成功,或业务错误已被捕获并写入结构化产物。
1 配置、输入文件、解析、模块加载、模型依赖或输出目录等致命错误。
2 argparse 参数使用错误。

10.附录 outputs/ 文件说明

本节描述输出目录中的文件。

10.1 outputs/B1_fixture/

输出文件 直接生成者 含义 格式
messages.json b1_agent_runtime.py fixture 模式 使用预设模块响应构造的完整 Agent 消息序列。 JSON 数组
trace.json b1_agent_runtime.py fixture 模式 B1 个人演示的轮次、分支、AIMessage 和 ToolMessage 轨迹。 JSON 对象
final_answer.md b1_agent_runtime.py fixture 模式 B1 从预设最终 AIMessage 中得到的回答。 Markdown

10.2 outputs/B2_skills/

输出文件 生成代码 含义 格式
calculator_result.json b2_run_skill.py calculator 最近一次 SkillResult。 JSON 对象
file_reader_result.json b2_run_skill.py file_reader 最近一次 SkillResult。 JSON 对象
local_file_search_result.json b2_run_skill.py local_file_search 最近一次 SkillResult。 JSON 对象
table_analyzer_result.json b2_run_skill.py table_analyzer 最近一次 SkillResult。 JSON 对象
format_converter_result.json b2_run_skill.py format_converter 最近一次 SkillResult,包含 formatted_text 和 generated_file_path。 JSON 对象
skill_run_log.jsonl b2_run_skill.py 五类 Skill 的累计运行日志。 JSONL

10.3 outputs/B3_tools/

输出文件 生成代码 含义 格式
tools_schema.json b3_tool_layer.py --export_schema basic_tools 的模型工具说明。 JSON 数组
tool_schema_report.json b3_tool_layer.py --export_schema 工具 schema 数量与名称摘要。 JSON 对象
tool_messages.json b3_tool_layer.py --execute 本次 tool calls 对应的 ToolMessage。 JSON 数组
tool_call_log.jsonl b3_tool_layer.py --execute tool calls 的累计执行明细。 JSONL

10.4 outputs/B4_llm/

输出文件 生成代码 含义 格式
<case>/raw_model_output.json b4_local_agent_llm.py B4 独立运行案例的原始输出和解析状态。 JSON 对象
<case>/ai_message.json b4_local_agent_llm.py B4 独立运行案例的规范化 AIMessage。 JSON 对象
<case>/llm_run_log.jsonl b4_local_agent_llm.py B4 独立运行案例的运行日志。 JSONL

10.5 outputs/B5_memory/

输出文件 生成代码 含义 格式
selected_memory.json b5_memory.py 查找模式 最近一次 memory 选择及截断结果。 JSON 对象
saved_memory.json b5_memory.py 保存模式 最近一次 memory 保存结果和目标路径。 JSON 对象
memory_log.jsonl b5_memory.py memory 查找/保存累计日志。 JSONL

10.6 outputs/B1_runtime/

输出文件 直接生成者 含义 格式
messages.json b1_agent_runtime.py 完整 Agent 消息序列。 JSON 数组
trace.json b1_agent_runtime.py 完整运行轨迹、轮次、状态和错误。 JSON 对象
final_answer.md b1_agent_runtime.py 最终回答。 Markdown
runtime_log.jsonl b1_agent_runtime.py B1 累计任务日志。 JSONL
selected_memory.json b5_memory.load_memory,由 B1 指定 outdir 注入消息前选择的 memory。 JSON 对象
memory_log.jsonl b5_memory.py,由 B1 调用 本轮 memory 查找及保存日志。 JSONL
saved_memory.json b5_memory.save_memory,由 B1 调用 本轮对话 memory 保存结果。 JSON 对象
tools_schema.json b3_tool_layer.get_tools_schema,由 B1 调用 本轮可用工具 schema。 JSON 数组
tool_schema_report.json b3_tool_layer.py,由 B1 调用 本轮工具集摘要。 JSON 对象
tool_messages.json B3 生成、B1 汇总 本轮所有 ToolMessage。 JSON 数组
tool_call_log.jsonl b3_tool_layer.execute_tool_calls,由 B1 调用 本轮工具执行明细。 JSONL
llm_calls/llm_call_001_raw_model_output.json b4_local_agent_llm.generate_ai_message 第一次 LLM 决策的原始输出。 JSON 对象
llm_calls/llm_call_001_ai_message.json b4_local_agent_llm.generate_ai_message 第一次标准 AIMessage,包含 tool call。 JSON 对象
llm_calls/llm_call_002_raw_model_output.json b4_local_agent_llm.generate_ai_message 第二次 LLM 决策的原始输出。 JSON 对象
llm_calls/llm_call_002_ai_message.json b4_local_agent_llm.generate_ai_message 第二次标准 AIMessage,包含 final content。 JSON 对象
llm_calls/llm_run_log.jsonl b4_local_agent_llm.py,由 B1 调用 本轮两次 LLM 调用日志。 JSONL

10.7 outputs/full_demo/

输出文件 直接生成者 含义 格式
messages.json b1_agent_runtime.py,由 run_full_demo.py 调用 完整演示消息序列。 JSON 数组
trace.json b1_agent_runtime.py 完整演示运行轨迹。 JSON 对象
final_answer.md b1_agent_runtime.py 完整演示最终回答。 Markdown
runtime_log.jsonl b1_agent_runtime.py 完整演示运行日志。 JSONL
selected_memory.json b5_memory.load_memory 完整演示选择的 memory。 JSON 对象
memory_log.jsonl b5_memory.py 完整演示的 memory 查找/保存日志。 JSONL
saved_memory.json b5_memory.save_memory 完整演示保存的对话 memory 信息。 JSON 对象
tools_schema.json b3_tool_layer.get_tools_schema 完整演示使用的工具 schema。 JSON 数组
tool_schema_report.json b3_tool_layer.py 完整演示工具集摘要。 JSON 对象
tool_messages.json B3 生成、B1 汇总 完整演示产生的 ToolMessage。 JSON 数组
tool_call_log.jsonl b3_tool_layer.execute_tool_calls 完整演示工具执行明细。 JSONL
llm_calls/llm_call_001_raw_model_output.json b4_local_agent_llm.py 第一次 LLM 原始输出。 JSON 对象
llm_calls/llm_call_001_ai_message.json b4_local_agent_llm.py 第一次 AIMessage,包含 tool call。 JSON 对象
llm_calls/llm_call_002_raw_model_output.json b4_local_agent_llm.py 第二次 LLM 原始输出。 JSON 对象
llm_calls/llm_call_002_ai_message.json b4_local_agent_llm.py 第二次 AIMessage,包含最终回答。 JSON 对象
llm_calls/llm_run_log.jsonl b4_local_agent_llm.py 完整演示 LLM 调用日志。 JSONL
demo_report.md run_full_demo.py 对完整演示状态、数据流、最终回答和文件清单的汇总。 Markdown
S
Description
No description provided
Readme
4.9 MiB
0 Stars 1 Watchers 0 Forks
Languages
Python 100%