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

核心流程概述

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

详细流程分析

1. 方法入口与初始化

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

2. 函数列表准备

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

相关推荐
say_fall29 分钟前
【AI大模型】MCP 模型上下文协议:客户端-服务器架构、JSON-RPC 消息与能力协商、工具发现与调用链路、与函数调用的分工
服务器·人工智能·架构
学长毕设1 小时前
基于SpringBoot的野生动物公益保护平台设计与实现-附源码
java·spring boot·后端
啾咪orJIUMI1 小时前
Vue 3 + 高德地图封装实战:点位、区域、Loca 流光与 Vue 信息窗体
前端·vue.js
掘金者阿豪1 小时前
AI数据库不只是向量检索:从数据语义到库内智能计算的技术演进
前端
梦里寻码1 小时前
我用 NestJS + Vue3 写了一套完整的研发管理系统(58 表 / 229 API / 130 项断言,全开源
前端·后端·算法
FRing031 小时前
vue2干货总结8(路由模块封装、router-link、声明式导航、路由重定向、编程式导航)
开发语言·前端·vue.js·vue2
SL_staff2 小时前
离散制造排程破局:JVS-APS 四步闭环落地实践(开发者视角)
java·产品·全栈
SameX2 小时前
HarmonyOS ArkUI Dialog 复用 用 @CustomDialog + enum type 做多类型统一管理的做法
前端
这个昵称不容易2 小时前
SpringBoot 美容院管理系统:232个Java文件315个接口,5套角色从预约到发货一整条链路
java·springboot·毕设
AiMan2 小时前
豆包爱学还是不可以导出左侧所有对话,只能单容导出,方法不对吗
前端