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

相关推荐
We་ct2 小时前
LeetCode 28. 找出字符串中第一个匹配项的下标:两种实现与深度解析
前端·算法·leetcode·typescript
CTO Plus技术服务中2 小时前
2026版Java web高并发面试题和参考答案
java·jvm·spring·spring cloud·面试·tomcat·java-consul
2301_803554522 小时前
Qt中connect()实现信号与槽连接这一核心机制
java·数据库·qt
峥嵘life2 小时前
Android16 EDLA【CTS】CtsNetTestCases存在fail项
android·java·linux·学习·elasticsearch
小码吃趴菜2 小时前
Shell脚本编程
前端·chrome
航Hang*2 小时前
计算机等级考试(三级Linux技术)--- 考纲与知识点
linux·运维·服务器·计算机三级·计算机等级考试
txinyu的博客2 小时前
虚拟内存
linux·运维·服务器
小yu学编程2 小时前
TCP协议详解
服务器·网络·tcp/ip·tcp协议·网络原理·tcp特性
心.c2 小时前
Vue3+Node.js实现文件上传并发控制与安全防线 进阶篇
前端·javascript·vue.js·安全·node.js