agent.py 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. """Agent 基类 — 100% 真实 LLM 调用 + 真实工具执行"""
  2. import json, time
  3. from openai import OpenAI
  4. from config import LLM_API_KEY, LLM_BASE_URL, LLM_MODEL, MAX_TOOL_ROUNDS
  5. from tools import TOOL_SCHEMAS, execute_tool
  6. class Agent:
  7. def __init__(self, name: str, icon: str, system_prompt: str, tool_names: list, model: str = None):
  8. self.name = name
  9. self.icon = icon
  10. self.system_prompt = system_prompt
  11. self.model = model or LLM_MODEL
  12. self.tools = [TOOL_SCHEMAS[n] for n in tool_names if n in TOOL_SCHEMAS]
  13. self.tool_names = tool_names
  14. self.client = OpenAI(api_key=LLM_API_KEY, base_url=LLM_BASE_URL)
  15. def chat(self, messages: list, emit=None) -> str:
  16. """带工具循环的真实 LLM 调用"""
  17. full_messages = [{"role": "system", "content": self.system_prompt}] + messages
  18. for round_i in range(MAX_TOOL_ROUNDS):
  19. t0 = time.time()
  20. kwargs = {"model": self.model, "messages": full_messages, "temperature": 0.3, "max_tokens": 4000}
  21. if self.tools:
  22. kwargs["tools"] = self.tools
  23. kwargs["tool_choice"] = "auto"
  24. resp = self.client.chat.completions.create(**kwargs)
  25. msg = resp.choices[0].message
  26. latency = int((time.time() - t0) * 1000)
  27. tokens = resp.usage.total_tokens if resp.usage else 0
  28. if emit:
  29. emit("llm_call", {"agent": self.name, "model": self.model, "latency_ms": latency, "tokens": tokens, "round": round_i + 1})
  30. # 无工具调用 → 最终文本
  31. if not msg.tool_calls:
  32. final = msg.content or ""
  33. if emit:
  34. emit("final_answer", {"agent": self.name, "answer": final, "rounds": round_i + 1})
  35. return final
  36. # 有工具调用 → 逐个执行
  37. full_messages.append(msg)
  38. for tc in msg.tool_calls:
  39. fn_name = tc.function.name
  40. try:
  41. fn_args = json.loads(tc.function.arguments)
  42. except json.JSONDecodeError:
  43. fn_args = {}
  44. t1 = time.time()
  45. result = execute_tool(fn_name, fn_args)
  46. tool_ms = int((time.time() - t1) * 1000)
  47. if emit:
  48. emit("tool_call", {
  49. "agent": self.name, "tool": fn_name,
  50. "args": fn_args, "result": result, "latency_ms": tool_ms,
  51. })
  52. full_messages.append({"role": "tool", "tool_call_id": tc.id, "content": result})
  53. return "[达到最大工具调用轮次限制]"