完整任务提示语:实现 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,请检查日志错误信息。

七、注意事项

  1. API 密钥:务必在项目根目录创建 .env 文件,并正确设置 DEEPSEEK_API_KEY不要将密钥硬编码在代码中
  2. 模型名称:Deepseek 当前提供的聊天模型为 deepseek-chat,请勿使用其他名称(除非明确通知)。
  3. base_url:必须为 https://api.deepseek.com/v1,末尾不要加多余的斜杠。
  4. 超时设置:建议设置 timeout=30,防止网络问题导致程序卡死。
  5. 日志:使用 Python 的 logging 模块记录错误,不要用 print(但测试代码中可以用 print)。
  6. LangChain 版本:我们使用 langchain-openai 包,它兼容 Deepseek 的 API。不要使用 langchain-community 中的其他封装。
  7. 返回 None 的处理:游戏主循环中调用此函数时,如果返回 None,可以显示“助手暂时无法提供建议”或忽略。

八、提交要求

  • 将实现后的 llm_hint.py 文件提交。
  • 确保代码符合 Python 3.12 语法,依赖已正确安装。
  • 代码注释清晰,关键步骤有说明。
  • 如果做了额外优化,请在注释中注明。

开始实现吧!如有任何疑问,请及时沟通。

posted @ 2026-03-15 22:10  神秘园欢迎您  阅读(31)  评论(0)    收藏  举报