TradingAgents/tradingagents/agents/risk_mgmt/neutral_debator.py

105 lines
4.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# -*- coding: utf-8 -*-
import time
import json
def create_neutral_debator(llm):
"""
建立一個中立的風險辯論員節點。
這個節點在風險評估辯論中扮演中立派的角色。
其目標是提供一個平衡的視角,權衡交易員決策的潛在利益和風險。
它會挑戰過於樂觀或過於謹慎的觀點,並倡導一個溫和、可持續的策略。
Args:
llm: 用於生成回應的語言模型。
Returns:
function: 一個代表中立辯論員節點的函式,可在 langgraph 中使用。
"""
def neutral_node(state) -> dict:
"""
中立辯論員節點的執行函式。
Args:
state (dict): 當前的圖狀態。
Returns:
dict: 更新後的狀態,包含新的風險辯論狀態。
"""
# 從狀態中獲取風險辯論的相關資訊
risk_debate_state = state["risk_debate_state"]
history = risk_debate_state.get("history", "")
neutral_history = risk_debate_state.get("neutral_history", "")
# 獲取其他辯論者的最新回應
current_risky_response = risk_debate_state.get("current_risky_response", "")
current_safe_response = risk_debate_state.get("current_safe_response", "")
# 從狀態中獲取各類分析報告
market_research_report = state["market_report"]
sentiment_report = state["sentiment_report"]
news_report = state["news_report"]
fundamentals_report = state["fundamentals_report"]
# 獲取交易員的決策
trader_decision = state["trader_investment_plan"]
# 定義文本截斷函數以避免超過 token 限制
def truncate_text(text, max_chars):
"""截斷文本到指定字符數"""
if len(text) <= max_chars:
return text
return text[:max_chars] + "\n...(內容已截斷)"
# 截斷各類輸入以控制 token 使用量
# 模型限制: 8192 tokens目標: < 3500 字符
market_research_report = truncate_text(market_research_report, 500)
sentiment_report = truncate_text(sentiment_report, 500)
news_report = truncate_text(news_report, 600)
fundamentals_report = truncate_text(fundamentals_report, 600)
trader_decision = truncate_text(trader_decision, 800)
history = truncate_text(history, 400)
current_risky_response = truncate_text(current_risky_response, 300)
current_safe_response = truncate_text(current_safe_response, 300)
# 建立提示 (prompt)
prompt = f"""作為中立風險分析師,您的角色是提供一個平衡的視角,權衡交易員決策或計畫的潛在利益和風險。您優先考慮一個全面的方法,評估其優缺點,同時考慮更廣泛的市場趨勢、潛在的經濟轉變和多元化策略。這是交易員的決策:
{trader_decision}
您的任務是挑戰激進和安全分析師,指出每個觀點可能過於樂觀或過於謹慎的地方。利用以下數據源的見解,支持一個溫和、可持續的策略來調整交易員的決策:
市場研究報告:{market_research_report}
社群媒體情緒報告:{sentiment_report}
最新世界事務報告:{news_report}
公司基本面報告:{fundamentals_report}
這是當前的對話歷史:{history} 這是激進分析師的最新回應:{current_risky_response} 這是安全分析師的最新回應:{current_safe_response}。如果其他觀點沒有回應,請不要憑空捏造,只需陳述您的觀點。
通過批判性地分析雙方,積極參與,指出激進和保守論點中的弱點,以倡導一個更平衡的方法。挑戰他們的每一個觀點,以說明為何一個溫和的風險策略可能提供兩全其美的方案,既提供增長潛力,又防範極端波動。專注於辯論,而不僅僅是呈現數據,旨在表明一個平衡的觀點可以帶來最可靠的結果。請以對話方式輸出,就像您在說話一樣,不帶任何特殊格式。"""
# 呼叫 LLM 生成回應
response = llm.invoke(prompt)
# 格式化論點
argument = f"中立分析師:{response.content}"
# 更新風險辯論狀態
new_risk_debate_state = {
"history": history + "\n" + argument,
"risky_history": risk_debate_state.get("risky_history", ""),
"safe_history": risk_debate_state.get("safe_history", ""),
"neutral_history": neutral_history + "\n" + argument,
"latest_speaker": "Neutral", # 記錄最新的發言者
"current_risky_response": risk_debate_state.get(
"current_risky_response", ""
),
"current_safe_response": risk_debate_state.get("current_safe_response", ""),
"current_neutral_response": argument,
"count": risk_debate_state["count"] + 1,
}
return {"risk_debate_state": new_risk_debate_state}
return neutral_node