LightAgent 0.2.1__tar.gz → 0.2.6__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.
@@ -11,6 +11,7 @@ import logging
11
11
  import os
12
12
  import httpx
13
13
  import importlib
14
+
14
15
  # 全局工具注册表
15
16
  _FUNCTION_MAPPINGS = {} # 工具名称 -> 工具函数
16
17
  _OPENAI_FUNCTION_SCHEMAS = [] # OpenAI 格式的工具描述
@@ -19,7 +20,6 @@ _PROMPT_FUNCTION_SCHEMAS = [] # prompt 格式的工具描述
19
20
  __version__ = "0.2.1" # 你可以根据需要设置版本号
20
21
 
21
22
 
22
-
23
23
  def register_tool_manually(tools: List[Union[str, Callable]]) -> bool:
24
24
  """
25
25
  手动注册多个工具,从函数属性中提取工具信息
@@ -114,6 +114,7 @@ def stream_generator(result):
114
114
  for chunk in result:
115
115
  yield chunk
116
116
 
117
+
117
118
  def dispatch_tool_old(tool_name: str, tool_params: Dict[str, Any]) -> str:
118
119
  """
119
120
  调用工具执行
@@ -150,6 +151,7 @@ def get_tools_str() -> str:
150
151
 
151
152
  class LightAgent:
152
153
  __version__ = "0.2.1" # 将版本号放在类中
154
+
153
155
  def __init__(
154
156
  self,
155
157
  *,
@@ -162,6 +164,7 @@ class LightAgent:
162
164
  websocket_base_url: str | httpx.URL | None = None,
163
165
  memory=None, # 支持外部传入记忆模块
164
166
  tree_of_thought: bool = False, # 是否启用链式思考
167
+ self_learning: bool = False, # 是否启用agent自我学习
165
168
  tools: List[Union[str, Callable]] = None, # 支持混合输入
166
169
  debug: bool = False, # 是否启用调试模式
167
170
  log_level: str = "INFO", # 日志级别(INFO, DEBUG, ERROR)
@@ -202,6 +205,7 @@ class LightAgent:
202
205
  self.model = model
203
206
  self.memory = memory
204
207
  self.tree_of_thought = tree_of_thought
208
+ self.self_learning = self_learning
205
209
 
206
210
  self.debug = debug
207
211
  self.log_level = log_level.upper()
@@ -236,8 +240,6 @@ class LightAgent:
236
240
  api_key=self.api_key
237
241
  )
238
242
 
239
-
240
-
241
243
  def get_tool(self, tool_name: str) -> Callable:
242
244
  """
243
245
  用于外部可以获取已加载的工具函数
@@ -358,6 +360,7 @@ class LightAgent:
358
360
  stream: bool = False,
359
361
  max_retry: int = 5,
360
362
  user_id: str = "default_user",
363
+ history: list = None,
361
364
  metadata: Optional[Dict] = None,
362
365
  ) -> Union[Generator[str, None, None], str]:
363
366
  """
@@ -368,10 +371,15 @@ class LightAgent:
368
371
  :param stream: 是否启用流式输出。
369
372
  :param max_retry: 最大重试次数。
370
373
  :param user_id: 用户 ID。
374
+ :param history: 历史对话 。
371
375
  :param metadata: 元数据。
372
376
  :return: 代理的回复。
373
377
  """
374
378
  self.log("INFO", "run", {"query": query, "user_id": user_id, "light_swarm": light_swarm, "stream": stream})
379
+ if history is None:
380
+ history = []
381
+ # 构建消息列表,先添加系统提示信息
382
+ params = {}
375
383
 
376
384
  # 1. 判断是否需要转移任务
377
385
  # if light_swarm:
@@ -396,14 +404,19 @@ class LightAgent:
396
404
  current_time = now.strftime("%H:%M:%S")
397
405
  system_prompt = f"##代理名称:{self.name} ##代理指令 /n{self.instructions} ##身份 /n {self.role} /n 请一步一步思考来完成用户的要求。尽可能完成用户的回答,如果有补充信息,请参考补充信息来调用工具,直到获取所有满足用户的提问所需的答案。 /n 今日的日期: {current_date} 当前时间: {current_time}"
398
406
  params = dict(model=self.model, stream=stream)
399
-
400
- # 3. 从记忆中检索相关内容
407
+ memory = ''
408
+ # 3. 从记忆中检索相关内容&保存记忆
401
409
  if self.memory:
402
410
  related_memories = self.memory.retrieve(query=query, user_id=user_id)
403
- query = self._build_context(query, related_memories)
411
+ memory = memory + self._build_context(related_memories)
404
412
  self.memory.store(data=query, user_id=user_id)
405
- else:
406
- query = query
413
+ if self.self_learning:
414
+ agent_memories = self.memory.retrieve(query=query, user_id=self.name)
415
+ memory = memory + self._build_agent_memory(agent_memories)
416
+ self.memory.store(data=query, user_id=self.name)
417
+
418
+ query = f"{memory}\n##用户提问:\n{query}"
419
+ # print(query)
407
420
 
408
421
  # 4. 拼接tools工具
409
422
  if self.tools:
@@ -418,10 +431,15 @@ class LightAgent:
418
431
  system_prompt = system_prompt + f" /n ##以下是问题的补充说明 /n {tot_response}"
419
432
  self.log("DEBUG", "tree_of_thought", {"response": tot_response})
420
433
 
421
- params["messages"] = [{"role": "system", "content": system_prompt}, {"role": "user", "content": query}]
434
+ # 6. 调用核心运行逻辑
435
+ params["messages"] = [{"role": "system", "content": system_prompt}]
436
+ # 将历史对话添加到消息列表中
437
+ for item in history:
438
+ params["messages"].append({"role": item["role"], "content": item["content"]})
439
+ # 最后添加当前用户的查询信息
440
+ params["messages"].append({"role": "user", "content": query})
422
441
  response = self.client.chat.completions.create(**params)
423
442
 
424
- # 6. 调用核心运行逻辑
425
443
  result = self._core_run_logic(response, params, stream, max_retry)
426
444
 
427
445
  return result
@@ -458,7 +476,11 @@ class LightAgent:
458
476
  # print(f"Streaming response from tool: {function_call.name}")
459
477
  for chunk in tool_response:
460
478
  # print("Received chunk:", chunk) # 打印每个 chunk
461
- combined_response += chunk # 将每个 chunk 叠加
479
+ if function_call_name == 'finish':
480
+ content = chunk.choices[0].delta.content or ""
481
+ combined_response += content # 将每个 chunk 叠加
482
+ else:
483
+ combined_response += chunk # 将每个 chunk 叠加
462
484
  if combined_response == "":
463
485
  combined_response = "".join(tool_response)
464
486
  tool_responses.append(combined_response) # 将叠加后的完整响应添加到列表
@@ -518,8 +540,9 @@ class LightAgent:
518
540
 
519
541
  for chunk in response:
520
542
  content = chunk.choices[0].delta.content or ""
521
- yield chunk # 流式返回内容
522
- output += content
543
+ if content:
544
+ yield chunk # 流式返回内容
545
+ output += content
523
546
 
524
547
  try:
525
548
  # 检查是否有工具调用
@@ -563,6 +586,8 @@ class LightAgent:
563
586
  "arguments": tool_call["arguments"],
564
587
  }
565
588
  self.log("INFO", "tool_call", {"function_call": function_call})
589
+ # 将工具的调用信息推送给开发者
590
+ yield function_call
566
591
 
567
592
  # 解析参数并调用工具
568
593
  try:
@@ -586,7 +611,11 @@ class LightAgent:
586
611
  combined_response = ""
587
612
  for chunk in tool_response:
588
613
  yield chunk
589
- combined_response += chunk # 将每个 chunk 叠加
614
+ if function_call_name == 'finish':
615
+ content = chunk.choices[0].delta.content or ""
616
+ combined_response += content # 将每个 chunk 叠加
617
+ else:
618
+ combined_response += chunk # 将每个 chunk 叠加
590
619
  tool_responses.append(combined_response) # 将叠加后的完整响应添加到列表
591
620
  else:
592
621
  # print(f"Non-streaming response from tool: {function_call['name']}")
@@ -722,25 +751,41 @@ class LightAgent:
722
751
  self.log("ERROR", "run_failed", {"error": str(e)})
723
752
  raise # 重新抛出异常以便调试
724
753
 
725
- def _build_context(self, user_input, related_memories):
754
+ def _build_context(self, related_memories):
726
755
  """
727
756
  构建上下文,将用户输入和记忆内容结合。
728
-
729
- :param user_input: 用户输入的问题或内容。
730
757
  :param related_memories: 从记忆中检索到的相关内容。
731
758
  :return: 结合记忆后的上下文。
732
759
  """
733
760
  if not related_memories or not related_memories["memories"]:
734
- return user_input
761
+ return ""
735
762
 
736
763
  memory_context = "\n".join([m["memory"] for m in related_memories["memories"]])
737
764
  if not memory_context:
738
- return user_input
765
+ return ""
739
766
 
740
- prompt = f"\n用户之前提到了\n{memory_context}。\n现在用户问\n{user_input}"
767
+ prompt = f"\n##用户偏好 \n用户之前提到了\n{memory_context}"
741
768
  self.log("DEBUG", "related_memories", {"memory_context": memory_context})
742
769
  return prompt
743
770
 
771
+ def _build_agent_memory(self, agent_memories):
772
+ """
773
+ 构建上下文,将用户输入和记忆内容结合。
774
+
775
+ :param agent_memories: 从记忆中检索到的相关内容。
776
+ :return: 结合记忆后的上下文。
777
+ """
778
+ if not agent_memories or not agent_memories["memories"]:
779
+ return ""
780
+
781
+ memory_context = "\n".join([m["memory"] for m in agent_memories["memories"]])
782
+ if not memory_context:
783
+ return ""
784
+
785
+ prompt = f"\n##以下是解决该问题的相关补充信息:\n{memory_context}。"
786
+ self.log("DEBUG", "agent_memories", {"memory_context": memory_context})
787
+ return prompt
788
+
744
789
  def run_thought(self, query: str, stream=False, tools=None):
745
790
  """使用思维树的方式 让大模型先根据get_tools_str生成一个解答用户query的工具使用计划"""
746
791
  tot_model = "deepseek-chat" # self.model