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

相关推荐
alice--小文子1 天前
cursor-mcp工具使用
java·服务器·前端
进阶小白猿1 天前
Java技术八股学习Day33
java·开发语言·学习
程序员敲代码吗1 天前
如何通过命令行启动COMSOL的参数化、批处理和集群扫描
java·c#·bash
晚霞的不甘1 天前
揭秘 CANN 内存管理:如何让大模型在小设备上“轻装上阵”?
前端·数据库·经验分享·flutter·3d
MX_93591 天前
Spring的bean工厂后处理器和Bean后处理器
java·后端·spring
小迷糊的学习记录1 天前
0.1 + 0.2 不等于 0.3
前端·javascript·面试
市场部需要一个软件开发岗位1 天前
JAVA开发常见安全问题:纵向越权
java·数据库·安全
历程里程碑1 天前
普通数组----合并区间
java·数据结构·python·算法·leetcode·职场和发展·tornado
梦帮科技1 天前
Node.js配置生成器CLI工具开发实战
前端·人工智能·windows·前端框架·node.js·json
程序员泠零澪回家种桔子1 天前
Spring AI框架全方位详解
java·人工智能·后端·spring·ai·架构