小智服务端chat入口工具调用流程

核心流程概述

connection.py中的chat方法是处理用户输入、调用LLM进行意图识别并执行工具调用的核心入口。该方法实现了完整的多轮工具调用机制,支持递归调用和并行工具执行。

详细流程分析

1. 方法入口与初始化

复制代码
def chat(self, query, depth=0):
    # 记录用户消息
    # 初始化会话ID和发送FIRST请求
    # 设置最大递归深度(默认5层)
    # ...

2. 函数列表准备

intent_typefunction_call且未达到最大深度时,获取可用函数列表:

复制代码
if self.intent_type == "function_call" and hasattr(self, "func_handler") and not force_final_answer:
    functions = self.func_handler.get_functions()

3. LLM调用

根据是否使用function_call模式,调用不同的LLM方法:

复制代码
if self.intent_type == "function_call" and functions is not None:
    # 使用带工具调用支持的响应方法
    llm_responses = self.llm.response_with_functions(
        self.session_id,
        self.dialogue.get_llm_dialogue_with_memory(memory_str, self.config.get("voiceprint", {})),
        functions=functions,
    )
else:
    # 使用普通响应方法
    llm_responses = self.llm.response(...)

4. 流式响应处理

遍历LLM返回的流式响应,检测工具调用:

复制代码
for response in llm_responses:
    # 检测是否包含工具调用
    if self.intent_type == "function_call" and functions is not None:
        content, tools_call = response
        # 处理工具调用信息
        if tools_call is not None and len(tools_call) > 0:
            tool_call_flag = True
            self._merge_tool_calls(tool_calls_list, tools_call)
    # ...

5. 工具调用解析与执行

当检测到工具调用时,解析调用信息并执行:

复制代码
if tool_call_flag:
    # 解析工具调用格式
    # 执行工具调用

    futures_with_data = [ ]

    for tool_call_data in tool_calls_list:
        future = asyncio.run_coroutine_threadsafe(
            self.func_handler.handle_llm_function_call(self, tool_call_data),
            self.loop,
        )
        futures_with_data.append((future, tool_call_data))
    # 等待所有工具调用完成

    tool_results = [ ]

    for future, tool_call_data in futures_with_data:
        result = future.result()
        tool_results.append((result, tool_call_data))
    # 处理工具调用结果
    self._handle_function_result(tool_results, depth=depth)

6. 工具结果处理

根据工具返回的Action类型进行不同处理:

复制代码
def _handle_function_result(self, tool_results, depth):
    for result, tool_call_data in tool_results:
        if result.action in [Action.RESPONSE, Action.NOTFOUND, Action.ERROR]:
            # 直接回复前端
            text = result.response if result.response else result.result
            self.tts.tts_one_sentence(self, ContentType.TEXT, content_detail=text)
            self.dialogue.put(Message(role="assistant", content=text))
        elif result.action == Action.REQLLM:
            # 需要LLM进一步处理,添加到对话历史并递归调用
            # ...
            self.dialogue.put(Message(role="tool", content=text))
            self.chat(None, depth=depth + 1)

7. 递归调用机制

当工具返回Action.REQLLM时,表示需要LLM基于工具结果进一步处理,此时会:

  1. 将工具结果添加到对话历史

  2. 递归调用chat方法,深度加1

  3. LLM基于新的对话历史生成最终回复

8. 会话结束

  • 存储完整对话内容

  • 发送LAST请求标记会话结束

  • 记录对话日志

关键特性

  1. 最大递归深度限制:防止无限循环,默认设置为5层

  2. 并行工具调用:支持同时调用多个工具

  3. 多种工具调用格式:支持JSON格式和文本格式的工具调用

  4. 灵活的结果处理:根据不同的Action类型进行不同的处理逻辑

  5. 记忆集成:结合记忆模块提供更智能的对话体验

流程图

复制代码
┌─────────────────────────────────────────────────────────┐
│                     调用 chat 方法                      │
└───────────────────────┬─────────────────────────────────┘
                        │
┌───────────────────────▼─────────────────────────────────┐
│                 初始化与配置检查                         │
│  - 记录用户消息                                          │
│  - 初始化会话ID                                          │
│  - 设置最大递归深度                                      │
└───────────────────────┬─────────────────────────────────┘
                        │
┌───────────────────────▼─────────────────────────────────┐
│                获取可用函数列表                          │
│  - 仅当intent_type为function_call且未达到最大深度时执行  │
│  - 调用func_handler.get_functions()                     │
└───────────────────────┬─────────────────────────────────┘
                        │
┌───────────────────────▼─────────────────────────────────┐
│                   调用LLM生成响应                        │
│  - 带工具调用支持的response_with_functions()            │
│  - 或普通的response()                                    │
└───────────────────────┬─────────────────────────────────┘
                        │
┌───────────────────────▼─────────────────────────────────┐
│                  处理流式响应                            │
│  - 遍历LLM返回的流式响应                                 │
│  - 检测工具调用标志                                       │
│  - 收集响应内容和工具调用信息                             │
└───────────────────────┬─────────────────────────────────┘
                        │
┌───────────────────────▼─────────────────────────────────┐
│                 检测工具调用标志                          │
│  ┌───────────────────────────────────────────────────┐  │
│  │  是                                               │  │
│  └───────────┬───────────────────────────────────────┘  │
│              │                                          │
│  ┌───────────▼───────────────────────────────────────┐  │
│  │            解析工具调用信息                        │  │
│  │  - 支持JSON格式和文本格式                         │  │
│  └───────────┬───────────────────────────────────────┘  │
│              │                                          │
│  ┌───────────▼───────────────────────────────────────┐  │
│  │            执行工具调用                            │  │
│  │  - 并行调用多个工具                                │  │
│  │  - 等待所有工具调用完成                            │  │
│  └───────────┬───────────────────────────────────────┘  │
│              │                                          │
│  ┌───────────▼───────────────────────────────────────┐  │
│  │            处理工具调用结果                        │  │
│  │  - 直接回复型结果(RESPONSE, NOTFOUND, ERROR)     │  │
│  │  - 需要LLM进一步处理的结果(REQLLM)               │  │
│  │    - 将结果添加到对话历史                          │  │
│  │    - 递归调用chat方法,深度+1                      │  │
│  └───────────────────────────────────────────────────┘  │
│                                                         │
│  ┌───────────────────────────────────────────────────┐  │
│  │  否                                               │  │
│  └───────────┬───────────────────────────────────────┘  │
│              │                                          │
│  ┌───────────▼───────────────────────────────────────┐  │
│  │            直接处理LLM响应                         │  │
│  │  - 存储对话内容                                    │  │
│  │  - 发送响应给用户                                  │  │
│  └───────────────────────────────────────────────────┘  │
└───────────────────────┬─────────────────────────────────┘
                        │
┌───────────────────────▼─────────────────────────────────┐
│                   结束会话                               │
│  - 发送LAST请求                                         │
│  - 标记LLM任务完成                                       │
│  - 记录对话日志                                         │
└─────────────────────────────────────────────────────────┘

代码优化建议

  1. 增加工具调用超时机制:当前实现中,future.result()调用会无限等待,建议添加超时参数,防止单个工具调用阻塞整个流程。

  2. 优化并行工具调用:考虑使用asyncio.gather()替代手动管理多个Future,提高代码可读性和性能。

  3. 增强错误处理:在工具调用和结果处理过程中增加更详细的错误日志和恢复机制。

  4. 添加工具调用缓存:对于相同参数的工具调用,可以考虑添加缓存机制,减少重复调用,提高响应速度。

  5. 优化递归调用:考虑使用迭代方式替代递归,避免深度过大时的栈溢出问题。

总结

connection.py中的chat方法实现了完整的意图识别和工具调用流程,支持多轮递归调用、并行工具执行和灵活的结果处理。该设计能够很好地满足复杂对话场景下的工具调用需求,为用户提供更智能、更丰富的交互体验。

相关推荐
NEXT066 分钟前
前端算法:从 O(n²) 到 O(n),列表转树的极致优化
前端·数据结构·算法
剪刀石头布啊12 分钟前
生成随机数,Math.random的使用
前端
剪刀石头布啊13 分钟前
css外边距重叠问题
前端
剪刀石头布啊13 分钟前
chrome单页签内存分配上限问题,怎么解决
前端
剪刀石头布啊15 分钟前
css实现一个宽高固定百分比的布局的一个方式
前端
Fcy64817 分钟前
Linux下 进程(一)(冯诺依曼体系、操作系统、进程基本概念与基本操作)
linux·运维·服务器·进程
袁袁袁袁满18 分钟前
Linux怎么查看最新下载的文件
linux·运维·服务器
剪刀石头布啊19 分钟前
js数组之快速组、慢数组、密集数组、稀松数组
前端
Ro Jace23 分钟前
计算机专业基础教材
java·开发语言
mango_mangojuice41 分钟前
Linux学习笔记(make/Makefile)1.23
java·linux·前端·笔记·学习