LightAgent 0.3.1__tar.gz → 0.3.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {lightagent-0.3.1 → lightagent-0.3.3}/LightAgent/la_core.py +192 -68
- {lightagent-0.3.1 → lightagent-0.3.3}/PKG-INFO +306 -107
- {lightagent-0.3.1 → lightagent-0.3.3}/README.de.md +20 -9
- {lightagent-0.3.1 → lightagent-0.3.3}/README.es.md +21 -12
- {lightagent-0.3.1 → lightagent-0.3.3}/README.fr.md +20 -10
- {lightagent-0.3.1 → lightagent-0.3.3}/README.ja.md +21 -11
- {lightagent-0.3.1 → lightagent-0.3.3}/README.ko.md +18 -11
- {lightagent-0.3.1 → lightagent-0.3.3}/README.md +66 -18
- {lightagent-0.3.1 → lightagent-0.3.3}/README.pt.md +18 -9
- {lightagent-0.3.1 → lightagent-0.3.3}/README.ru.md +40 -11
- {lightagent-0.3.1 → lightagent-0.3.3}/README.zh-CN.md +79 -15
- {lightagent-0.3.1 → lightagent-0.3.3}/pyproject.toml +4 -2
- {lightagent-0.3.1 → lightagent-0.3.3}/LICENSE +0 -0
- {lightagent-0.3.1 → lightagent-0.3.3}/LightAgent/__init__.py +0 -0
|
@@ -3,33 +3,32 @@
|
|
|
3
3
|
|
|
4
4
|
"""
|
|
5
5
|
作者: [weego/WXAI-Team]
|
|
6
|
-
版本: 0.3.
|
|
7
|
-
最后更新: 2025-
|
|
6
|
+
版本: 0.3.3
|
|
7
|
+
最后更新: 2025-05-05
|
|
8
8
|
"""
|
|
9
9
|
|
|
10
|
-
import
|
|
11
|
-
|
|
12
|
-
from copy import deepcopy
|
|
10
|
+
import asyncio
|
|
11
|
+
import importlib
|
|
13
12
|
import importlib.util
|
|
14
|
-
import
|
|
13
|
+
import inspect
|
|
15
14
|
import json
|
|
16
|
-
from datetime import datetime
|
|
17
|
-
from openai import OpenAI
|
|
18
15
|
import logging
|
|
19
16
|
import os
|
|
20
|
-
import
|
|
21
|
-
import
|
|
22
|
-
from openai.types.chat import ChatCompletionChunk
|
|
23
|
-
import inspect
|
|
17
|
+
import random
|
|
18
|
+
import re
|
|
24
19
|
import traceback
|
|
25
|
-
from mcp import ClientSession, StdioServerParameters, types
|
|
26
20
|
from contextlib import AsyncExitStack
|
|
21
|
+
from copy import deepcopy
|
|
22
|
+
from datetime import datetime
|
|
23
|
+
from functools import partial
|
|
24
|
+
from typing import List, Dict, Any, Callable, Union, Optional, Generator, AsyncGenerator
|
|
25
|
+
from uuid import uuid4
|
|
27
26
|
|
|
27
|
+
import httpx
|
|
28
|
+
from mcp import ClientSession, StdioServerParameters
|
|
28
29
|
from mcp.client.sse import sse_client
|
|
29
30
|
from mcp.client.stdio import stdio_client
|
|
30
|
-
import
|
|
31
|
-
from functools import partial
|
|
32
|
-
|
|
31
|
+
from openai.types.chat import ChatCompletionChunk
|
|
33
32
|
|
|
34
33
|
# 全局工具注册表
|
|
35
34
|
_FUNCTION_MAPPINGS = {} # 工具名称 -> 工具函数
|
|
@@ -37,7 +36,10 @@ _FUNCTION_INFO = {} # 工具名称 -> 工具info信息
|
|
|
37
36
|
_OPENAI_FUNCTION_SCHEMAS = [] # OpenAI 格式的工具描述
|
|
38
37
|
_PROMPT_FUNCTION_SCHEMAS = [] # prompt 格式的工具描述
|
|
39
38
|
|
|
40
|
-
__version__ = "0.3.
|
|
39
|
+
__version__ = "0.3.3" # 你可以根据需要设置版本号
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
# openai.langfuse_auth_check()
|
|
41
43
|
|
|
42
44
|
|
|
43
45
|
def register_tool_manually(tools: List[Union[str, Callable]]) -> bool:
|
|
@@ -181,6 +183,44 @@ def get_tools_str() -> str:
|
|
|
181
183
|
return tools_str
|
|
182
184
|
|
|
183
185
|
|
|
186
|
+
def filter_tools_schemas(refined_content: str) -> json:
|
|
187
|
+
"""
|
|
188
|
+
根据refined_content中的工具列表过滤全局_OPENAI_FUNCTION_SCHEMAS
|
|
189
|
+
:param refined_content: 包含工具列表的JSON字符串
|
|
190
|
+
"""
|
|
191
|
+
# global _OPENAI_FUNCTION_SCHEMAS # 声明操作全局变量
|
|
192
|
+
"""安全解析可能包含 Markdown 代码块的 JSON"""
|
|
193
|
+
refined_content = refined_content.strip()
|
|
194
|
+
if refined_content.startswith('```json') and refined_content.endswith('```'):
|
|
195
|
+
refined_content = refined_content[7:-3].strip() # 去除 ```json 和 ```
|
|
196
|
+
try:
|
|
197
|
+
# 解析工具列表
|
|
198
|
+
parsed_data: Dict[str, List[Dict]] = json.loads(refined_content)
|
|
199
|
+
valid_tools = {tool["name"].strip().lower() for tool in parsed_data.get("tools", [])}
|
|
200
|
+
|
|
201
|
+
# 原地过滤操作
|
|
202
|
+
filtered_schemas: List[Dict] = []
|
|
203
|
+
for schema in _OPENAI_FUNCTION_SCHEMAS:
|
|
204
|
+
if not isinstance(schema, dict):
|
|
205
|
+
continue
|
|
206
|
+
|
|
207
|
+
# 深度检查结构
|
|
208
|
+
function_info = schema.get("function", {})
|
|
209
|
+
if isinstance(function_info, dict):
|
|
210
|
+
schema_name = function_info.get("name", "").strip().lower()
|
|
211
|
+
if schema_name in valid_tools:
|
|
212
|
+
filtered_schemas.append(schema)
|
|
213
|
+
|
|
214
|
+
# 直接替换全局变量内容
|
|
215
|
+
# _OPENAI_FUNCTION_SCHEMAS[:] = filtered_schemas
|
|
216
|
+
return filtered_schemas
|
|
217
|
+
|
|
218
|
+
except (json.JSONDecodeError, KeyError, AttributeError) as e:
|
|
219
|
+
# 错误处理:清空工具列表并记录日志
|
|
220
|
+
# _OPENAI_FUNCTION_SCHEMAS.clear()
|
|
221
|
+
raise ValueError(f"工具过滤失败: {str(e)}") from e
|
|
222
|
+
|
|
223
|
+
|
|
184
224
|
class MCPClientManager:
|
|
185
225
|
"""增强版MCP客户端管理器"""
|
|
186
226
|
|
|
@@ -379,7 +419,7 @@ class MCPClientManager:
|
|
|
379
419
|
|
|
380
420
|
|
|
381
421
|
class LightAgent:
|
|
382
|
-
__version__ = "0.3.
|
|
422
|
+
__version__ = "0.3.3" # 将版本号放在类中
|
|
383
423
|
|
|
384
424
|
def __init__(
|
|
385
425
|
self,
|
|
@@ -391,16 +431,18 @@ class LightAgent:
|
|
|
391
431
|
api_key: str | None = None, # 模型 api key
|
|
392
432
|
base_url: str | httpx.URL | None = None, # 模型 base url
|
|
393
433
|
websocket_base_url: str | httpx.URL | None = None, # 模型 websocket base url
|
|
394
|
-
memory=None, # 支持外部传入记忆模块
|
|
434
|
+
memory: str | None = None, # 支持外部传入记忆模块
|
|
395
435
|
tree_of_thought: bool = False, # 是否启用链式思考
|
|
396
436
|
tot_model: str | None = None, # 链式思考模型
|
|
397
437
|
tot_api_key: str | None = None, # 链式思考模型API密钥
|
|
398
438
|
tot_base_url: str | httpx.URL | None = None, # 链式思考模型base_url
|
|
439
|
+
filter_tools: bool = True, # 是否启用工具过滤
|
|
399
440
|
self_learning: bool = False, # 是否启用agent自我学习
|
|
400
441
|
tools: List[Union[str, Callable]] = None, # 支持工具混合输入
|
|
401
442
|
debug: bool = False, # 是否启用调试模式
|
|
402
443
|
log_level: str = "INFO", # 日志级别(INFO, DEBUG, ERROR)
|
|
403
|
-
log_file: Optional[str] = None # 日志文件路径
|
|
444
|
+
log_file: Optional[str] = None, # 日志文件路径
|
|
445
|
+
tracetools: Optional[dict] = None, # log跟踪工具
|
|
404
446
|
) -> None:
|
|
405
447
|
"""
|
|
406
448
|
初始化 LightAgent。
|
|
@@ -417,10 +459,12 @@ class LightAgent:
|
|
|
417
459
|
:param tot_model: 使用的模型名称。
|
|
418
460
|
:param tot_api_key: API 密钥。
|
|
419
461
|
:param tot_base_url: API 的基础 URL。
|
|
462
|
+
:param filter_tools: 是否启用工具过滤。
|
|
420
463
|
:param tools: 工具列表,支持函数名称(字符串)或函数对象。
|
|
421
464
|
:param debug: 是否启用调试模式。
|
|
422
465
|
:param log_level: 日志级别(INFO, DEBUG, ERROR)。
|
|
423
466
|
:param log_file: 日志文件路径。
|
|
467
|
+
:param tracetools: log跟踪工具。
|
|
424
468
|
"""
|
|
425
469
|
self.mcp_setting = None
|
|
426
470
|
self.mcp_client = None
|
|
@@ -443,9 +487,11 @@ class LightAgent:
|
|
|
443
487
|
self.memory = memory
|
|
444
488
|
self.tree_of_thought = tree_of_thought
|
|
445
489
|
self.self_learning = self_learning
|
|
490
|
+
self.filter_tools = filter_tools
|
|
446
491
|
|
|
447
492
|
self.debug = debug
|
|
448
493
|
self.log_level = log_level.upper()
|
|
494
|
+
self.traceid = "" # 用于存储 traceid
|
|
449
495
|
# 确保 log 目录存在
|
|
450
496
|
log_dir = 'logs'
|
|
451
497
|
if not os.path.exists(log_dir):
|
|
@@ -463,7 +509,6 @@ class LightAgent:
|
|
|
463
509
|
self.load_tools(tools)
|
|
464
510
|
# register_tool_manually(tools)
|
|
465
511
|
|
|
466
|
-
|
|
467
512
|
if api_key is None:
|
|
468
513
|
raise ValueError(
|
|
469
514
|
"The api_key client option must be set either by passing api_key to the client or by setting the OPENAI_API_KEY environment variable"
|
|
@@ -474,10 +519,6 @@ class LightAgent:
|
|
|
474
519
|
if base_url is None:
|
|
475
520
|
base_url = f"https://api.openai.com/v1"
|
|
476
521
|
|
|
477
|
-
self.client = OpenAI(
|
|
478
|
-
base_url=base_url,
|
|
479
|
-
api_key=self.api_key
|
|
480
|
-
)
|
|
481
522
|
if self.tree_of_thought:
|
|
482
523
|
if tot_api_key is None:
|
|
483
524
|
tot_api_key = api_key
|
|
@@ -486,10 +527,36 @@ class LightAgent:
|
|
|
486
527
|
if not tot_model:
|
|
487
528
|
tot_model = "deepseek-r1" # 默认思维推理模型为deepseek-r1
|
|
488
529
|
self.tot_model = tot_model
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
530
|
+
|
|
531
|
+
if tracetools is None:
|
|
532
|
+
self.tracetools = []
|
|
533
|
+
if tracetools:
|
|
534
|
+
self.tracetools = tracetools
|
|
535
|
+
# 初始化工具列表
|
|
536
|
+
from langfuse.openai import openai as la_openai
|
|
537
|
+
la_openai.langfuse_public_key = self.tracetools['TraceToolConfig']['langfuse_public_key']
|
|
538
|
+
la_openai.langfuse_secret_key = self.tracetools['TraceToolConfig']['langfuse_secret_key']
|
|
539
|
+
la_openai.langfuse_enabled = self.tracetools['TraceToolConfig'][
|
|
540
|
+
'langfuse_enabled'] # Default is True, set to False to disable Langfuse
|
|
541
|
+
la_openai.langfuse_host = self.tracetools['TraceToolConfig']['langfuse_host'] # 🇪🇺 EU region
|
|
542
|
+
la_openai.base_url = base_url
|
|
543
|
+
la_openai.api_key = self.api_key
|
|
544
|
+
self.client = la_openai
|
|
545
|
+
if self.tree_of_thought:
|
|
546
|
+
la_openai.base_url = tot_base_url
|
|
547
|
+
la_openai.api_key = tot_api_key
|
|
548
|
+
self.tot_client = la_openai
|
|
549
|
+
else:
|
|
550
|
+
from openai import OpenAI as la_openai
|
|
551
|
+
self.client = la_openai(
|
|
552
|
+
base_url=base_url,
|
|
553
|
+
api_key=self.api_key
|
|
492
554
|
)
|
|
555
|
+
if self.tree_of_thought:
|
|
556
|
+
self.tot_client = la_openai(
|
|
557
|
+
base_url=tot_base_url,
|
|
558
|
+
api_key=tot_api_key
|
|
559
|
+
)
|
|
493
560
|
|
|
494
561
|
def get_tool(self, tool_name: str) -> Callable:
|
|
495
562
|
"""
|
|
@@ -596,7 +663,10 @@ class LightAgent:
|
|
|
596
663
|
"""
|
|
597
664
|
if not self.debug:
|
|
598
665
|
return
|
|
599
|
-
|
|
666
|
+
if self.traceid is not None:
|
|
667
|
+
log_message = f"[TraceID: {self.traceid}] {action}: {data}"
|
|
668
|
+
else:
|
|
669
|
+
log_message = f"{action}: {data}"
|
|
600
670
|
if level == "DEBUG":
|
|
601
671
|
self.logger.debug(log_message)
|
|
602
672
|
elif level == "INFO":
|
|
@@ -605,8 +675,8 @@ class LightAgent:
|
|
|
605
675
|
self.logger.error(log_message)
|
|
606
676
|
|
|
607
677
|
async def setup_mcp(
|
|
608
|
-
|
|
609
|
-
|
|
678
|
+
self,
|
|
679
|
+
mcp_setting: dict | None = None, # mcp 设置
|
|
610
680
|
):
|
|
611
681
|
if mcp_setting:
|
|
612
682
|
self.mcp_setting = mcp_setting
|
|
@@ -638,6 +708,7 @@ class LightAgent:
|
|
|
638
708
|
:param metadata: 元数据。
|
|
639
709
|
:return: 代理的回复。
|
|
640
710
|
"""
|
|
711
|
+
self.traceid = uuid4().hex
|
|
641
712
|
self.log("INFO", "run", {"query": query, "user_id": user_id, "light_swarm": light_swarm, "stream": stream})
|
|
642
713
|
if history is None:
|
|
643
714
|
history = []
|
|
@@ -654,19 +725,25 @@ class LightAgent:
|
|
|
654
725
|
# self._transfer_to_agent(light_swarm.agents[target_agent_name], query, stream=stream)
|
|
655
726
|
# return # 立即结束当前生成器
|
|
656
727
|
|
|
657
|
-
#
|
|
728
|
+
# 0. 判断是否需要转移任务
|
|
658
729
|
if light_swarm:
|
|
659
730
|
result = self._handle_task_transfer(query, light_swarm, stream)
|
|
660
731
|
if result is not None:
|
|
661
732
|
return result
|
|
662
733
|
|
|
663
|
-
#
|
|
734
|
+
# 1. 正常处理任务
|
|
664
735
|
now = datetime.now()
|
|
665
736
|
current_date = now.strftime("%Y-%m-%d")
|
|
666
737
|
current_time = now.strftime("%H:%M:%S")
|
|
667
738
|
system_prompt = f"##代理名称:{self.name} ##代理指令 /n{self.instructions} ##身份 /n {self.role} /n 请一步一步思考来完成用户的要求。尽可能完成用户的回答,如果有补充信息,请参考补充信息来调用工具,直到获取所有满足用户的提问所需的答案。 /n 今日的日期: {current_date} 当前时间: {current_time}"
|
|
668
739
|
params = dict(model=self.model, stream=stream)
|
|
669
740
|
memory = ''
|
|
741
|
+
|
|
742
|
+
# 2.添加langfuse的session
|
|
743
|
+
if self.tracetools:
|
|
744
|
+
params["session_id"] = self.traceid
|
|
745
|
+
self.log("DEBUG", "Query Trace ID", {"query": query})
|
|
746
|
+
|
|
670
747
|
# 3. 从记忆中检索相关内容&保存记忆
|
|
671
748
|
if self.memory:
|
|
672
749
|
related_memories = self.memory.retrieve(query=query, user_id=user_id)
|
|
@@ -680,19 +757,29 @@ class LightAgent:
|
|
|
680
757
|
query = f"{memory}\n##用户提问:\n{query}"
|
|
681
758
|
# print(query)
|
|
682
759
|
|
|
683
|
-
# 4.
|
|
684
|
-
|
|
760
|
+
# 4. 思维链
|
|
761
|
+
active_tools = []
|
|
762
|
+
if self.tree_of_thought:
|
|
763
|
+
tot_response, active_tools = self.run_thought(query=query)
|
|
764
|
+
system_prompt = system_prompt + f" /n ##以下是问题的补充说明 /n {tot_response}"
|
|
765
|
+
self.log("DEBUG", "tree_of_thought", {"response": tot_response, "active_tools": active_tools})
|
|
766
|
+
|
|
767
|
+
# 5. 拼接tools工具
|
|
768
|
+
# 带类型校验 自适应工具机制
|
|
769
|
+
try:
|
|
770
|
+
tools = active_tools if (
|
|
771
|
+
len(active_tools) > 0
|
|
772
|
+
) else get_tools()
|
|
773
|
+
except TypeError:
|
|
774
|
+
tools = get_tools()
|
|
775
|
+
# 带类型校验 自适应工具机制
|
|
776
|
+
# tools = get_tools() # v0.2.X的工具选取机制
|
|
685
777
|
if tools:
|
|
686
778
|
self.log("DEBUG", "register_tools", {"tools": list(_FUNCTION_MAPPINGS.keys())})
|
|
779
|
+
self.log("DEBUG", "active_tools", {"tools": tools})
|
|
687
780
|
params["tools"] = tools
|
|
688
781
|
params["tool_choice"] = "auto"
|
|
689
782
|
|
|
690
|
-
# 5. 思维链
|
|
691
|
-
if self.tree_of_thought:
|
|
692
|
-
tot_response = self.run_thought(query=query)
|
|
693
|
-
system_prompt = system_prompt + f" /n ##以下是问题的补充说明 /n {tot_response}"
|
|
694
|
-
self.log("DEBUG", "tree_of_thought", {"response": tot_response})
|
|
695
|
-
|
|
696
783
|
# 6. 调用核心运行逻辑
|
|
697
784
|
params["messages"] = [{"role": "system", "content": system_prompt}]
|
|
698
785
|
# 将历史对话添加到消息列表中
|
|
@@ -700,6 +787,7 @@ class LightAgent:
|
|
|
700
787
|
params["messages"].append({"role": item["role"], "content": item["content"]})
|
|
701
788
|
# 最后添加当前用户的查询信息
|
|
702
789
|
params["messages"].append({"role": "user", "content": query})
|
|
790
|
+
|
|
703
791
|
response = self.client.chat.completions.create(**params)
|
|
704
792
|
|
|
705
793
|
result = self._core_run_logic(response, params, stream, max_retry)
|
|
@@ -1075,10 +1163,10 @@ class LightAgent:
|
|
|
1075
1163
|
:param related_memories: 从记忆中检索到的相关内容。
|
|
1076
1164
|
:return: 结合记忆后的上下文。
|
|
1077
1165
|
"""
|
|
1078
|
-
if not related_memories or not related_memories["
|
|
1166
|
+
if not related_memories or not related_memories["results"]:
|
|
1079
1167
|
return ""
|
|
1080
1168
|
|
|
1081
|
-
memory_context = "\n".join([m["memory"] for m in related_memories["
|
|
1169
|
+
memory_context = "\n".join([m["memory"] for m in related_memories["results"]])
|
|
1082
1170
|
if not memory_context:
|
|
1083
1171
|
return ""
|
|
1084
1172
|
|
|
@@ -1093,10 +1181,10 @@ class LightAgent:
|
|
|
1093
1181
|
:param agent_memories: 从记忆中检索到的相关内容。
|
|
1094
1182
|
:return: 结合记忆后的上下文。
|
|
1095
1183
|
"""
|
|
1096
|
-
if not agent_memories or not agent_memories["
|
|
1184
|
+
if not agent_memories or not agent_memories["results"]:
|
|
1097
1185
|
return ""
|
|
1098
1186
|
|
|
1099
|
-
memory_context = "\n".join([m["memory"] for m in agent_memories["
|
|
1187
|
+
memory_context = "\n".join([m["memory"] for m in agent_memories["results"]])
|
|
1100
1188
|
if not memory_context:
|
|
1101
1189
|
return ""
|
|
1102
1190
|
|
|
@@ -1104,7 +1192,7 @@ class LightAgent:
|
|
|
1104
1192
|
self.log("DEBUG", "agent_memories", {"memory_context": memory_context})
|
|
1105
1193
|
return prompt
|
|
1106
1194
|
|
|
1107
|
-
def run_thought(self, query: str
|
|
1195
|
+
def run_thought(self, query: str) -> tuple:
|
|
1108
1196
|
"""使用思维树的方式 让大模型先根据get_tools_str生成一个解答用户query的工具使用计划"""
|
|
1109
1197
|
tot_model = self.tot_model # self.model
|
|
1110
1198
|
tools = get_tools_str()
|
|
@@ -1113,30 +1201,66 @@ class LightAgent:
|
|
|
1113
1201
|
now = datetime.now()
|
|
1114
1202
|
current_date = now.strftime("%Y-%m-%d")
|
|
1115
1203
|
current_time = now.strftime("%H:%M:%S")
|
|
1116
|
-
system_prompt = f"""
|
|
1204
|
+
system_prompt = f"""你是一个智能助手,请根据用户输入的问题,结合工具使用计划,生成一个思维树,并按照思维树依次调用工具步骤,最终生成一个最终回答。\n 今日的日期: {current_date} 当前时间: {current_time} \n 工具列表: {tools}"""
|
|
1117
1205
|
self.log("DEBUG", "run_thought", {"system_prompt": system_prompt})
|
|
1118
1206
|
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1207
|
+
try:
|
|
1208
|
+
# 1. 第一次请求,生成初始的工具使用计划
|
|
1209
|
+
params = dict(model=tot_model,
|
|
1210
|
+
messages=[{"role": "system", "content": system_prompt}, {"role": "user", "content": query}],
|
|
1211
|
+
stream=False)
|
|
1212
|
+
response = self.tot_client.chat.completions.create(**params)
|
|
1213
|
+
initial_content = response.choices[0].message.content
|
|
1214
|
+
self.log("DEBUG", "initial_response", {"response": initial_content})
|
|
1215
|
+
|
|
1216
|
+
# 2. 第二次请求,请求大模型反思并生成新的工具使用规划
|
|
1217
|
+
reflection_prompt = "请反思你的回答,请严格按照<工具列表>中的工具来规划,不可以创造其他新的工具。请输出新的任务规划,不要输出其他分析和回答。"
|
|
1218
|
+
reflection_params = dict(model=tot_model, messages=[
|
|
1219
|
+
{"role": "user", "content": f"{system_prompt} /n 开始思考问题: {query}"},
|
|
1220
|
+
{"role": "assistant", "content": initial_content},
|
|
1221
|
+
{"role": "user", "content": reflection_prompt}
|
|
1222
|
+
], stream=False)
|
|
1223
|
+
self.log("DEBUG", "reflection_params", {"params": reflection_params})
|
|
1224
|
+
reflection_response = self.tot_client.chat.completions.create(**reflection_params)
|
|
1225
|
+
refined_content = reflection_response.choices[0].message.content
|
|
1226
|
+
self.log("DEBUG", "refined_response", {"response": refined_content})
|
|
1227
|
+
|
|
1228
|
+
# 获取工具的使用集合
|
|
1229
|
+
tool_reflection_prompt = """请严格按以下要求执行:
|
|
1230
|
+
1. 分析问题需求并规划需要使用的工具
|
|
1231
|
+
2. 仅输出包含工具名称的JSON格式结果
|
|
1232
|
+
3. 使用以下结构(示例):
|
|
1233
|
+
{"tools": [{"name": "工具名称1"}, {"name": "工具名称2"}]}
|
|
1234
|
+
4. 不要包含任何解释性内容"""
|
|
1235
|
+
|
|
1236
|
+
tool_reflection_params = dict(
|
|
1237
|
+
model=tot_model,
|
|
1238
|
+
messages=[
|
|
1239
|
+
{"role": "system", "content": system_prompt},
|
|
1240
|
+
{"role": "user", "content": f"问题分析请求:{query}"},
|
|
1241
|
+
{"role": "assistant", "content": refined_content},
|
|
1242
|
+
{"role": "user", "content": tool_reflection_prompt}
|
|
1243
|
+
],
|
|
1244
|
+
response_format={"type": "json_object"}, # 强制JSON输出格式
|
|
1245
|
+
stream=False
|
|
1246
|
+
)
|
|
1247
|
+
|
|
1248
|
+
self.log("DEBUG", "tool_reflection_params", {"params": tool_reflection_params})
|
|
1249
|
+
tool_reflection_response = self.tot_client.chat.completions.create(**tool_reflection_params)
|
|
1250
|
+
tool_reflection_result = tool_reflection_response.choices[0].message.content
|
|
1251
|
+
self.log("DEBUG", "tool_reflection_result", {"result": tool_reflection_result})
|
|
1252
|
+
|
|
1253
|
+
# 3.执行自适应工具过滤
|
|
1254
|
+
current_tools = []
|
|
1255
|
+
if self.filter_tools:
|
|
1256
|
+
current_tools = filter_tools_schemas(tool_reflection_result)
|
|
1257
|
+
self.log("DEBUG", "current_tools", {"get_tools": current_tools})
|
|
1258
|
+
|
|
1259
|
+
return refined_content, current_tools
|
|
1260
|
+
|
|
1261
|
+
except Exception as e:
|
|
1262
|
+
self.log("ERROR", "run_thought_failure", {"error": str(e)})
|
|
1263
|
+
raise RuntimeError(f"思维链执行失败: {str(e)}") from e
|
|
1140
1264
|
|
|
1141
1265
|
def _detect_intent(self, query: str, light_swarm=None) -> Optional[Dict]:
|
|
1142
1266
|
"""
|