完整任务提示语:实现 LLM 队友提示功能(Deepseek 版)
完整任务提示语:实现 LLM 队友提示功能(Deepseek 版)
一、任务背景
在《极妙幻境》的 BOSS 战中,玩家可以输入命令(如 /hint)请求 AI 助手提供战术建议。你需要实现一个函数 get_llm_hint,该函数根据当前牌局状态构造提示词,调用 Deepseek 大语言模型,并返回一句简短实用的建议(中文)。
二、环境与项目结构
2.1 环境要求
- Python 3.12.10
- 依赖库已由项目维护者锁定在
requirements.txt(内容如下)。你只需在项目根目录执行pip install -r requirements.txt安装。
# requirements.txt
langchain>=1.0.10,<2
langchain-core>=1.0.10,<2
langchain-openai>=1.0.10,<2
openai>=1.0.0,<2
python-dotenv==1.0.0
pytest>=7.4.0,<8
2.2 项目结构(已建立)
your_game_project/
│
├── requirements.txt
├── .env (你需要创建,存放 API 密钥)
│
├── src/
│ ├── __init__.py
│ └── game_logic/
│ ├── __init__.py
│ ├── card_acquisition.py (已有)
│ ├── morality.py (已有)
│ ├── boss_ai.py (已有)
│ └── llm_hint.py (**你要实现的文件**)
│
├── prompts/
│ └── hint_prompt.txt (提示词模板,已提供)
│
└── tests/ (可选,可暂时不写)
2.3 已有文件内容
prompts/hint_prompt.txt(请勿修改,直接使用)
你是一位经验丰富的修仙者,正在帮助一位道友(玩家)进行一场心魔对战。
游戏规则:
- 双方轮流出牌,每轮出牌者扣着出1-3张牌,并宣称一个类型(善/恶/中立),可用万能牌冒充任何类型。
- 对方可以选择质疑(翻开验证)、跟牌(自己也出牌)或不跟(清空桌面)。
- 先出完手牌者胜。
当前牌局状态:
- 你的手牌:善{good}张,恶{evil}张,中立{neutral}张,万能{wild}张。
- 对方手牌剩余:{boss_hand}张。
- 桌面累积牌数:{table_pile}张。
- 上一轮对方宣称了【{last_claim}】。
- 现在轮到你【{turn}】。
请根据以上信息,给出简短实用的建议(一句话即可),例如“对方可能在虚张声势,建议质疑”或“你善牌较多,可以跟牌宣称善”。
.env 文件(你需要创建,放在项目根目录)
DEEPSEEK_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxx # 替换为你的 Deepseek API Key
三、函数签名与参数
你需要实现 src/game_logic/llm_hint.py,包含以下函数:
from typing import Optional, Dict
def get_llm_hint(
player_hand: Dict[str, int], # 玩家手牌分布,键为 'good','evil','neutral','wild'
boss_hand_count: int, # BOSS手牌总数(玩家可见)
table_pile_count: int, # 桌面累积牌数
last_claim: Optional[str], # 上一轮对方宣称的类型,如 'good','evil','neutral';若无则为 None
is_player_turn: bool # True 表示轮到玩家出牌,False 表示轮到玩家回应
) -> Optional[str]:
"""
根据当前牌局状态,调用 Deepseek 模型返回一句战术建议(中文)。
如果调用失败,返回 None。
"""
# 待实现
四、实现步骤(必须遵循)
4.1 加载环境变量
在文件开头使用 python-dotenv 加载 .env 文件,确保 DEEPSEEK_API_KEY 可用。
from dotenv import load_dotenv
load_dotenv()
4.2 读取提示词模板
模板文件路径为项目根目录下的 prompts/hint_prompt.txt。你可以通过计算相对路径来定位:
import os
# 获取当前文件所在目录的上一级(src/game_logic -> src -> 项目根)
PROJECT_ROOT = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
TEMPLATE_PATH = os.path.join(PROJECT_ROOT, "prompts", "hint_prompt.txt")
with open(TEMPLATE_PATH, "r", encoding="utf-8") as f:
template_str = f.read()
为了提高性能,建议在模块加载时读取一次,不要在函数内重复读取。
4.3 初始化 Deepseek 模型
使用 langchain_openai.ChatOpenAI 类(因为它兼容 OpenAI 格式),指定 Deepseek 的 API 地址和模型名称。注意:不要使用 OpenAI 的默认地址。
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(
model="deepseek-chat", # Deepseek 聊天模型
temperature=0.2, # 温度设为较低值,使建议更稳定
base_url="https://api.deepseek.com/v1", # Deepseek API 端点
api_key=os.getenv("DEEPSEEK_API_KEY"), # 从环境变量读取
timeout=30 # 可选,设置超时
)
你也可以在函数内部每次调用时创建 LLM 实例,但建议在模块级别创建一次,避免重复初始化开销。
4.4 构造提示词
使用 langchain_core.prompts.ChatPromptTemplate 将模板字符串转换为模板对象,并用参数填充。
from langchain_core.prompts import ChatPromptTemplate
prompt_template = ChatPromptTemplate.from_template(template_str)
formatted_prompt = prompt_template.format(
good=player_hand.get('good', 0),
evil=player_hand.get('evil', 0),
neutral=player_hand.get('neutral', 0),
wild=player_hand.get('wild', 0),
boss_hand=boss_hand_count,
table_pile=table_pile_count,
last_claim=last_claim if last_claim else "无",
turn="出牌" if is_player_turn else "回应"
)
注意:formatted_prompt 是一个字符串,可以直接传给 LLM。
4.5 调用模型并返回结果
try:
response = llm.invoke(formatted_prompt) # 返回的是 AIMessage 对象
hint = response.content.strip()
return hint
except Exception as e:
# 记录错误日志
import logging
logging.error(f"LLM hint failed: {e}")
return None
建议在文件开头配置日志(可选),以便调试。
五、完整代码示例(整合)
# src/game_logic/llm_hint.py
import os
import logging
from typing import Optional, Dict
from dotenv import load_dotenv
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI
# 加载环境变量
load_dotenv()
# 读取模板文件(模块加载时执行一次)
PROJECT_ROOT = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
TEMPLATE_PATH = os.path.join(PROJECT_ROOT, "prompts", "hint_prompt.txt")
with open(TEMPLATE_PATH, "r", encoding="utf-8") as f:
template_str = f.read()
# 初始化 LLM(模块加载时执行一次)
llm = ChatOpenAI(
model="deepseek-chat",
temperature=0.2,
base_url="https://api.deepseek.com/v1",
api_key=os.getenv("DEEPSEEK_API_KEY"),
timeout=30
)
logger = logging.getLogger(__name__)
def get_llm_hint(
player_hand: Dict[str, int],
boss_hand_count: int,
table_pile_count: int,
last_claim: Optional[str],
is_player_turn: bool
) -> Optional[str]:
"""
根据当前牌局状态,调用 Deepseek 模型返回一句战术建议。
"""
try:
prompt_template = ChatPromptTemplate.from_template(template_str)
formatted_prompt = prompt_template.format(
good=player_hand.get('good', 0),
evil=player_hand.get('evil', 0),
neutral=player_hand.get('neutral', 0),
wild=player_hand.get('wild', 0),
boss_hand=boss_hand_count,
table_pile=table_pile_count,
last_claim=last_claim if last_claim else "无",
turn="出牌" if is_player_turn else "回应"
)
response = llm.invoke(formatted_prompt)
hint = response.content.strip()
return hint
except Exception as e:
logger.error(f"LLM hint failed: {e}")
return None
六、测试建议
你可以在文件末尾添加一个简单的测试代码块,方便验证功能(非必须,但推荐):
if __name__ == "__main__":
# 测试样例
hint = get_llm_hint(
player_hand={'good':5, 'evil':3, 'neutral':2, 'wild':1},
boss_hand_count=10,
table_pile_count=4,
last_claim='good',
is_player_turn=True
)
print("建议:", hint)
运行该文件(确保已设置好 API 密钥)即可看到输出。如果返回 None,请检查日志错误信息。
七、注意事项
- API 密钥:务必在项目根目录创建
.env文件,并正确设置DEEPSEEK_API_KEY。不要将密钥硬编码在代码中。 - 模型名称:Deepseek 当前提供的聊天模型为
deepseek-chat,请勿使用其他名称(除非明确通知)。 - base_url:必须为
https://api.deepseek.com/v1,末尾不要加多余的斜杠。 - 超时设置:建议设置
timeout=30,防止网络问题导致程序卡死。 - 日志:使用 Python 的
logging模块记录错误,不要用print(但测试代码中可以用print)。 - LangChain 版本:我们使用
langchain-openai包,它兼容 Deepseek 的 API。不要使用langchain-community中的其他封装。 - 返回 None 的处理:游戏主循环中调用此函数时,如果返回 None,可以显示“助手暂时无法提供建议”或忽略。
八、提交要求
- 将实现后的
llm_hint.py文件提交。 - 确保代码符合 Python 3.12 语法,依赖已正确安装。
- 代码注释清晰,关键步骤有说明。
- 如果做了额外优化,请在注释中注明。
开始实现吧!如有任何疑问,请及时沟通。

浙公网安备 33010602011771号