doc:add doc to researchers model

This commit is contained in:
2403_87681582 2025-12-07 11:33:44 +08:00
parent 13b826a31d
commit c130b8f395
4 changed files with 94 additions and 23 deletions

View File

@ -1,2 +1,2 @@
ALPHA_VANTAGE_API_KEY=alpha_vantage_api_key_placeholder ALPHA_VANTAGE_API_KEY=W47FRS433AD7DVGQ
OPENAI_API_KEY=openai_api_key_placeholder OPENAI_API_KEY=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

View File

@ -204,8 +204,8 @@ def select_deep_thinking_agent(provider) -> str:
"google": [ "google": [
("Gemini 2.0 Flash-Lite - Cost efficiency and low latency", "gemini-2.0-flash-lite"), ("Gemini 2.0 Flash-Lite - Cost efficiency and low latency", "gemini-2.0-flash-lite"),
("Gemini 2.0 Flash - Next generation features, speed, and thinking", "gemini-2.0-flash"), ("Gemini 2.0 Flash - Next generation features, speed, and thinking", "gemini-2.0-flash"),
("Gemini 2.5 Flash - Adaptive thinking, cost efficiency", "gemini-2.5-flash-preview-05-20"), ("Gemini 2.5 Flash - Adaptive thinking, cost efficiency", "gemini-2.5-flash"),
("Gemini 2.5 Pro", "gemini-2.5-pro-preview-06-05"), ("Gemini 2.5 Pro", "gemini-2.5-pro"),
], ],
"openrouter": [ "openrouter": [
("DeepSeek V3 - a 685B-parameter, mixture-of-experts model", "deepseek/deepseek-chat-v3-0324:free"), ("DeepSeek V3 - a 685B-parameter, mixture-of-experts model", "deepseek/deepseek-chat-v3-0324:free"),

View File

@ -3,37 +3,58 @@ import time
import json import json
# 定义一个创建“看空”研究员Bear Researcher节点的工厂函数
def create_bear_researcher(llm, memory): def create_bear_researcher(llm, memory):
def bear_node(state) -> dict: """
investment_debate_state = state["investment_debate_state"] 创建看空分析师Bear Analyst LangGraph 节点函数
history = investment_debate_state.get("history", "")
bear_history = investment_debate_state.get("bear_history", "")
Args:
llm: 语言模型实例用于生成分析和论点
memory: 外部记忆/检索系统用于获取历史教训
Returns:
Callable: 接受当前状态并返回更新后的状态的节点函数 (bear_node)
"""
def bear_node(state) -> dict:
"""
看空分析师节点的核心逻辑
根据全局状态中的报告和辩论历史生成看空论点并更新状态
"""
# --- 1. 获取当前状态数据 ---
investment_debate_state = state["investment_debate_state"]
# 提取辩论历史和上一轮多头Bull的回复
history = investment_debate_state.get("history", "")
current_response = investment_debate_state.get("current_response", "") current_response = investment_debate_state.get("current_response", "")
# 提取所有研究报告作为论证的证据
market_research_report = state["market_report"] market_research_report = state["market_report"]
sentiment_report = state["sentiment_report"] sentiment_report = state["sentiment_report"]
news_report = state["news_report"] news_report = state["news_report"]
fundamentals_report = state["fundamentals_report"] fundamentals_report = state["fundamentals_report"]
# --- 2. 记忆检索与格式化 ---
# 合并所有报告,作为检索记忆的查询(寻找相似情况下的历史教训)
curr_situation = f"{market_research_report}\n\n{sentiment_report}\n\n{news_report}\n\n{fundamentals_report}" curr_situation = f"{market_research_report}\n\n{sentiment_report}\n\n{news_report}\n\n{fundamentals_report}"
# 从外部记忆中检索历史记录/教训
past_memories = memory.get_memories(curr_situation, n_matches=2) past_memories = memory.get_memories(curr_situation, n_matches=2)
# 格式化检索到的历史教训,作为 Prompt 的一部分
past_memory_str = "" past_memory_str = ""
for i, rec in enumerate(past_memories, 1): for rec in past_memories:
past_memory_str += rec["recommendation"] + "\n\n" past_memory_str += rec.get("recommendation", "") + "\n\n"
# --- 3. 构建 Prompt 并调用 LLM ---
prompt = f"""You are a Bear Analyst making the case against investing in the stock. Your goal is to present a well-reasoned argument emphasizing risks, challenges, and negative indicators. Leverage the provided research and data to highlight potential downsides and counter bullish arguments effectively. prompt = f"""You are a Bear Analyst making the case against investing in the stock. Your goal is to present a well-reasoned argument emphasizing risks, challenges, and negative indicators. Leverage the provided research and data to highlight potential downsides and counter bullish arguments effectively.
Key points to focus on: Key points to focus on:
- Risks and Challenges: Highlight factors like market saturation, financial instability, or macroeconomic threats.
- Risks and Challenges: Highlight factors like market saturation, financial instability, or macroeconomic threats that could hinder the stock's performance. - Bull Counterpoints: Critically analyze the bull argument with specific data and sound reasoning.
- Competitive Weaknesses: Emphasize vulnerabilities such as weaker market positioning, declining innovation, or threats from competitors. - Engagement: Present your argument in a conversational style, directly engaging with the bull analyst's points.
- Negative Indicators: Use evidence from financial data, market trends, or recent adverse news to support your position.
- Bull Counterpoints: Critically analyze the bull argument with specific data and sound reasoning, exposing weaknesses or over-optimistic assumptions.
- Engagement: Present your argument in a conversational style, directly engaging with the bull analyst's points and debating effectively rather than simply listing facts.
Resources available: Resources available:
Market research report: {market_research_report} Market research report: {market_research_report}
Social media sentiment report: {sentiment_report} Social media sentiment report: {sentiment_report}
Latest world affairs news: {news_report} Latest world affairs news: {news_report}
@ -41,21 +62,32 @@ Company fundamentals report: {fundamentals_report}
Conversation history of the debate: {history} Conversation history of the debate: {history}
Last bull argument: {current_response} Last bull argument: {current_response}
Reflections from similar situations and lessons learned: {past_memory_str} Reflections from similar situations and lessons learned: {past_memory_str}
Use this information to deliver a compelling bear argument, refute the bull's claims, and engage in a dynamic debate that demonstrates the risks and weaknesses of investing in the stock. You must also address reflections and learn from lessons and mistakes you made in the past. Use this information to deliver a compelling bear argument, refute the bull's claims, and engage in a dynamic debate that demonstrates the risks and weaknesses of investing in the stock. You must also address reflections and learn from lessons and mistakes you made in the past.
""" """
# 调用 LLM 生成看空分析师的回复
response = llm.invoke(prompt) response = llm.invoke(prompt)
# 格式化看空分析师的论点,加上身份前缀
argument = f"Bear Analyst: {response.content}" argument = f"Bear Analyst: {response.content}"
# --- 4. 更新全局状态 ---
new_investment_debate_state = { new_investment_debate_state = {
# 更新完整的辩论历史
"history": history + "\n" + argument, "history": history + "\n" + argument,
"bear_history": bear_history + "\n" + argument, # 更新看空方的历史记录 (便于后续总结和自我反思)
"bull_history": investment_debate_state.get("bull_history", ""), "bear_history": investment_debate_state.get("bear_history", "") + "\n" + argument,
# 将当前回复设置为看空方的论点,供下一轮(如看多方)使用
"current_response": argument, "current_response": argument,
# 增加辩论的轮数计数
"count": investment_debate_state["count"] + 1, "count": investment_debate_state["count"] + 1,
# 保持看多方的历史不变 (从旧状态中获取)
"bull_history": investment_debate_state.get("bull_history", ""),
} }
# 返回包含更新后的投资辩论状态的字典,用于 LangGraph 传递
return {"investment_debate_state": new_investment_debate_state} return {"investment_debate_state": new_investment_debate_state}
# 返回定义的节点函数
return bear_node return bear_node

View File

@ -3,25 +3,54 @@ import time
import json import json
# 定义一个创建“看多”研究员Bull Researcher节点的工厂函数
def create_bull_researcher(llm, memory): def create_bull_researcher(llm, memory):
"""
创建看多分析师Bull Analyst LangGraph 节点函数
Args:
llm: 语言模型实例用于生成分析和论点
memory: 外部记忆/检索系统用于获取历史经验和教训
Returns:
Callable: 接受当前状态并返回更新后的状态的节点函数 (bull_node)
"""
# 内部定义的节点函数,接收整个状态字典
def bull_node(state) -> dict: def bull_node(state) -> dict:
"""
看多分析师节点的核心逻辑
根据全局状态中的报告和辩论历史生成看多论点并更新状态
"""
# --- 1. 获取当前状态数据 ---
investment_debate_state = state["investment_debate_state"] investment_debate_state = state["investment_debate_state"]
# 提取辩论的完整历史和上一轮空头Bear的回复
history = investment_debate_state.get("history", "") history = investment_debate_state.get("history", "")
bull_history = investment_debate_state.get("bull_history", "") bull_history = investment_debate_state.get("bull_history", "")
current_response = investment_debate_state.get("current_response", "") current_response = investment_debate_state.get("current_response", "")
# 提取所有研究报告作为论证的证据
market_research_report = state["market_report"] market_research_report = state["market_report"]
sentiment_report = state["sentiment_report"] sentiment_report = state["sentiment_report"]
news_report = state["news_report"] news_report = state["news_report"]
fundamentals_report = state["fundamentals_report"] fundamentals_report = state["fundamentals_report"]
# --- 2. 记忆检索与格式化 ---
# 合并所有报告,作为检索记忆的查询
curr_situation = f"{market_research_report}\n\n{sentiment_report}\n\n{news_report}\n\n{fundamentals_report}" curr_situation = f"{market_research_report}\n\n{sentiment_report}\n\n{news_report}\n\n{fundamentals_report}"
# 从外部记忆中检索历史记录/教训
past_memories = memory.get_memories(curr_situation, n_matches=2) past_memories = memory.get_memories(curr_situation, n_matches=2)
# 格式化检索到的历史教训,作为 Prompt 的一部分
past_memory_str = "" past_memory_str = ""
for i, rec in enumerate(past_memories, 1): for rec in past_memories:
past_memory_str += rec["recommendation"] + "\n\n" # 假设每个记忆记录包含一个 "recommendation" 字段
past_memory_str += rec.get("recommendation", "") + "\n\n"
# --- 3. 构建 Prompt 并调用 LLM ---
# 构建发送给 LLM 的提示Prompt指导其扮演看多分析师的角色
prompt = f"""You are a Bull Analyst advocating for investing in the stock. Your task is to build a strong, evidence-based case emphasizing growth potential, competitive advantages, and positive market indicators. Leverage the provided research and data to address concerns and counter bearish arguments effectively. prompt = f"""You are a Bull Analyst advocating for investing in the stock. Your task is to build a strong, evidence-based case emphasizing growth potential, competitive advantages, and positive market indicators. Leverage the provided research and data to address concerns and counter bearish arguments effectively.
Key points to focus on: Key points to focus on:
@ -42,18 +71,28 @@ Reflections from similar situations and lessons learned: {past_memory_str}
Use this information to deliver a compelling bull argument, refute the bear's concerns, and engage in a dynamic debate that demonstrates the strengths of the bull position. You must also address reflections and learn from lessons and mistakes you made in the past. Use this information to deliver a compelling bull argument, refute the bear's concerns, and engage in a dynamic debate that demonstrates the strengths of the bull position. You must also address reflections and learn from lessons and mistakes you made in the past.
""" """
# 调用 LLM 生成看多分析师的回复
response = llm.invoke(prompt) response = llm.invoke(prompt)
# 格式化看多分析师的论点,加上身份前缀
argument = f"Bull Analyst: {response.content}" argument = f"Bull Analyst: {response.content}"
# --- 4. 更新全局状态 ---
new_investment_debate_state = { new_investment_debate_state = {
# 更新完整的辩论历史
"history": history + "\n" + argument, "history": history + "\n" + argument,
# 更新看多方的历史记录 (便于后续总结)
"bull_history": bull_history + "\n" + argument, "bull_history": bull_history + "\n" + argument,
# 保持看空方的历史不变 (从旧状态中获取)
"bear_history": investment_debate_state.get("bear_history", ""), "bear_history": investment_debate_state.get("bear_history", ""),
# 将当前回复设置为看多方的论点,供下一轮(如看空方)使用
"current_response": argument, "current_response": argument,
# 增加辩论的轮数计数
"count": investment_debate_state["count"] + 1, "count": investment_debate_state["count"] + 1,
} }
# 返回包含更新后的投资辩论状态的字典,用于 LangGraph 传递
return {"investment_debate_state": new_investment_debate_state} return {"investment_debate_state": new_investment_debate_state}
return bull_node # 返回定义的节点函数 (工厂函数模式)
return bull_node