ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

基于 hello_agents 构建“猜猜我是谁“交互式猜人物游戏:LLM 角色扮演、搜索增强与语义匹配的完整实战

基于 hello_agents 构建“猜猜我是谁“交互式猜人物游戏:LLM 角色扮演、搜索增强与语义匹配的完整实战 基于 hello_agents 构建猜猜我是谁交互式猜人物游戏LLM 角色扮演、搜索增强与语义匹配的完整实战【免费下载链接】hello-agents 《从零开始构建智能体》——从零开始的智能体原理与实践教程项目地址: https://gitcode.com/GitHub_Trending/he/hello-agents本篇文章以开源仓库 hello-agents 中Co-creation-projects/afei-GuessWhoAmI子项目为蓝本系统拆解如何基于hello_agents框架从零搭建一个由 LLM 驱动、前后端完整的交互式猜人物游戏Agent 随机扮演历史人物、神话人物或网络红人玩家通过多轮对话提问、有限次提示与语义猜测来揭开谜底。读完本文你将掌握 LLM 动态人物生成、Tavily 搜索增强提示、SimpleAgent 角色扮演、LLM 语义匹配与 Wikipedia 图片检索这一整套可复用的 Agent 应用开发方案。项目定位与核心设计亮点GuessWhoAmI猜猜我是谁是一个基于hello_agents框架开发的交互式猜人物游戏。AI Agent 随机扮演一位历史人物、神话人物或网络红人用户通过多轮对话提问来猜测其身份。项目在 README 中总结了六大特色LLM 动态生成人物—— 每局由大模型随机生成人物涵盖中西历史、神话、虚构角色、网络红人等多个领域不重复沉浸式角色扮演—— Agent 以第一人称扮演人物语气符合其性格与时代背景回答具有迷惑性和引导性Tavily 搜索增强—— 自动搜索人物资料生成由模糊到具体的 3 条提示️猜对后展示人物图片—— 猜对后通过 Wikipedia 搜索并展示人物图片语义猜测匹配—— 使用 LLM 语义判断猜测是否正确支持别名、外号等多种表达⚡FastAPI 高性能后端 现代化 Web 前端。从架构角度看这个项目最值得学习的地方在于它把随机性注入防人物重复、外部搜索工具Tavily、无工具纯对话 Agent角色扮演与LLM 作为判断器语义匹配四种 Agent 能力组合在一条完整的游戏流水线中是hello_agents框架多工具协同的典型范例。项目结构与模块划分afei-GuessWhoAmI/ ├── restart.sh # 一键启动脚本前后端 ├── backend/ │ ├── main.py # FastAPI 入口API 路由 │ ├── agents.py # Agent 核心逻辑人物生成、角色扮演、猜测判断 │ ├── game_logic.py # 游戏状态管理GameSession │ ├── config.py # 配置管理Settings 单例 │ ├── models.py # Pydantic 请求/响应模型 │ ├── requirements.txt # Python 依赖 │ ├── .env.example # 环境变量模板 │ └── tools/ │ ├── tavily_search_tool.py # Tavily 搜索工具生成提示 │ └── search_image_tool.py # Wikipedia 图片搜索工具 ├── frontend/ │ ├── index.html # 主页面 │ ├── style.css # 样式文件 │ └── app.js # 交互逻辑 └── logs/ ├── backend.log # 后端运行日志 └── frontend.log # 前端服务日志模块职责非常清晰main.py只负责 HTTP 层与路由分发game_logic.py管理游戏状态机agents.py封装所有 LLM 相关能力两个工具类继承hello_agents的Tool基类独立完成外部能力接入前端则是零框架依赖的原生 HTML/CSS/JS。核心架构一局游戏的完整流水线一局游戏的启动并非简单地把名字交给 Agent而是经历一条**生成 → 搜索 → 扮演**的三阶段流水线全部由HistoricalFigureAgent的构造函数串联见 agents.py人物生成调用_generate_figure()由 LLM 随机生成名称 一句话简介提示预生成调用_generate_hints()先用 Tavily 搜索人物资料再让 LLM 基于资料产出 3 条由模糊到具体的提示角色扮演 Agent 创建调用_create_roleplay_agent()把人物简介注入 system prompt创建一个enable_tool_callingFalse的纯对话SimpleAgent。下面逐一深入每一阶段的源码实现。LLM 动态人物生成如何避免每次都是同一个人人物生成是整个游戏的随机性来源。项目通过三层机制确保每次开局的人物不重复第一层领域候选池随机采样。agents.py 定义了_FIGURE_DOMAINS包含 13 个领域中国古代帝王、文人墨客、军事家、中国神话人物、西游记人物、三国人物、西方历史人物、西方神话人物、世界科学家、知名虚构角色、现代体育明星、中国近现代人物、网络红人与 UP 主。每次开局随机选一个领域作为 system prompt 的方向约束。第二层随机种子 时间戳注入。_build_random_figure_prompt()agents.py会生成一个 10000~99999 的随机种子写入 system prompt同时 user 消息里还会注入毫秒级时间戳ts int(time.time() * 1000)与一个 1~9999 的随机数。这种做法一方面是打乱 LLM 缓存的相似请求另一方面从 prompt 层面强制模型发散。第三层严格输出格式解析 兜底。prompt 要求模型严格输出两行名称人物名称 简介一句话概括其性格特点与主要成就50字以内_parse_figure()agents.py逐行解析兼容全角/半角冒号与姓名/名称两种前缀一旦解析失败或 LLM 调用异常则回退到_fallback_figure()内置的人物池孔子、孙悟空、武则天、诸葛亮、哈利·波特随机兜底保证游戏在任何情况下都能开局。Tavily 搜索增强由模糊到具体的三条提示提示hint是本游戏的辅助机制设计上要求由模糊到具体第 1 条最模糊、第 3 条最具体且不能直接说出答案。其实现分两步Tavily 搜索人物资料TavilySearchTooltavily_search_tool.py继承hello_agents.tools.base.Tool调用TavilyClient.search()使用search_depthbasic、max_results5、include_answerFalse只取原始检索结果不生成 AI 摘要。出于 token 成本与提示质量平衡工具只取前 1 条结果并经过正则清洗去除 URL、折叠空白、去重标点、规整省略号后截断到 300 字符。LLM 生成提示将搜索资料与答案名一起交给 LLM由_HINT_SYSTEM_PROMPTagents.py约束每条提示单独一行、格式为提示N内容、由模糊到具体、不能直接说出答案。_parse_hints()用正则^(提示\d[:]\s*|\d[\.、]\s*)清洗行前缀不足 3 条时用通用 fallback 提示补齐。值得注意的是Tavily 未配置时系统不会崩溃_generate_hints()在self._search_tool为空时直接走_fallback_hints()返回这是一个广为人知的事物等通用提示实现优雅降级详见 agents.py。沉浸式角色扮演SimpleAgent 的人格注入角色扮演 Agent 是游戏体验的核心。_create_roleplay_agent()创建了一个nameguess_who_agent、enable_tool_callingFalse的纯对话SimpleAgent——扮演阶段不需要任何工具避免 Agent 在回答时偏离角色。其灵魂在于_ROLEPLAY_SYSTEM_PROMPTagents.py它要求 Agent以人物第一人称回答语气措辞符合性格与时代背景必须直接针对用户问题给出明确回应是的/不是/确实如此不能回避或答非所问在明确回应基础上用符合人物身份的语气补充一句每次回答 1~2 句话保持简短回答基于人物真实生平不编造严禁在任何情况下说出人物名称包括姓名、字号、封号、外号等一切称谓与人物完全无关的问题用符合身份的方式婉转说明。先明确作答 再角色化补充的指令设计兼顾了游戏可玩性玩家能获得有效信息与沉浸感回答有性格是角色扮演类 Agent prompt 的实用模板。语义猜测匹配与画像展示玩家提交猜测后HistoricalFigureAgent.make_guess()agents.py的处理策略是精确匹配优先guess.strip().lower() actual_name.lower()LLM 语义匹配兜底精确匹配失败时调用_semantic_match()使用_SEMANTIC_MATCH_PROMPT判断以下两个名称是否指代同一个人物或事物只需回答是或否让 LLM 判断结果以result.startswith(是)判定。这样孙悟空 vs 齐天大圣李太白 vs 李白这类别名、外号表达也能正确命中。猜对后后端调用SearchImageTool.search_photos()search_image_tool.py从 Wikipedia 拉取画像。该工具不走容易被 403 的w/api.php搜索接口而是直接调用 REST Summary API中文优先、英文兜底见源码中的_ZH_SUMMARY_URL/_EN_SUMMARY_URL并伪造浏览器 User-Agent 规避反爬最终把缩略图与原图 URL 随接口返回前端据此渲染画像画廊。游戏状态管理GameSession 与 GameManager游戏状态由 game_logic.py 管理GameSession每局一个实例持有session_idUUID、current_figure当前人物、hints预生成提示列表、questions_asked/hints_used已用提问/提示计数、is_game_over/is_correct、guess_history猜测历史并从配置读取max_questions10与max_hints3。ask_question()提问计数自增达到上限即置is_game_overTruemake_guess()先精确匹配、再由注入的semantic_match_fn兜底猜对或次数用尽即结束游戏并返回figure_infoget_hint()按序返回预生成提示同时返回hint_level与剩余次数get_game_status()汇总会话状态供前端刷新。GameManager维护active_sessions字典提供create_session/get_session/end_session/cleanup_old_sessions默认清理超过 60 分钟未更新的会话并暴露全局单例game_manager。在 main.py 中会话存储采用session_id - (GameSession, HistoricalFigureAgent)的元组配对active_sessions字典每次请求通过get_session_pair()校验会话存在性会话不存在返回 404。环境要求与配置环境要求Python 3.8ModelScope API Key必须提供 OpenAI 兼容的 LLM 接口Tavily API Key必须用于搜索增强提示可在 Tavily 平台注册获取依赖清单见 requirements.txtfastapi0.104.1、uvicorn[standard]0.24.0、hello_agents0.1.0、python-dotenv1.0.0、pydantic2.5.0、httpx0.25.2、tavily-python0.3.0、requests2.31.0。环境变量与配置参数配置管理在 config.py 中实现Settings类在模块导入时通过load_dotenv加载backend/.env并以单例get_config()方式供全项目读取。环境变量模板见 backend/.env.example。配置项代码默认值说明LLM_MODEL_IDqwen-flash使用的 LLM 模型推荐 flash 系列以降低延迟LLM_API_KEY空ModelScope API Key必填LLM_BASE_URLhttps://api-inference.modelscope.cn/v1/LLM 接口地址OpenAI 兼容LLM_TIMEOUT30秒LLM 请求超时.env.example示例值给出180以应对长响应TAVILY_API_KEY空Tavily 搜索 Key必填未配置时自动降级为 fallback 提示MAX_QUESTIONS10每局最大提问次数代码级常量不读 .envMAX_HINTS3每局最大提示次数代码级常量不读 .envHOST/PORT0.0.0.0/8000后端监听地址与端口代码级常量需要注意MAX_QUESTIONS、MAX_HINTS、HOST、PORT属于代码级默认值不存放在 .env见 config.py 注释如需调整需直接修改源码。Settings.validate()会在启动时检查LLM_API_KEY是否为空并打印警告。快速开始1. 安装依赖cd /path/to/repo/Co-creation-projects/afei-GuessWhoAmI/backend pip install -r requirements.txt2. 配置环境变量复制模板并填写配置cp backend/.env.example backend/.env编辑backend/.env# LLM 配置ModelScope API必填 LLM_MODEL_IDqwen-flash LLM_API_KEYyour_modelscope_api_key LLM_BASE_URLhttps://api-inference.modelscope.cn/v1/ LLM_TIMEOUT180 # Tavily 搜索 API必填用于搜索增强提示 TAVILY_API_KEYyour_tavily_api_key3. 一键启动推荐使用 restart.sh 同时启动前后端cd /path/to/repo/Co-creation-projects/afei-GuessWhoAmI bash restart.sh脚本会自动停止已有的前后端进程按端口lsof清理 按进程名pgrep清理启动后端FastAPI端口8000启动前端Pythonhttp.server端口3000通过wait_for_port轮询等待服务就绪最长 15 秒超时报错并提示查看日志。启动成功后输出示例✅ All services started successfully! Backend → http://localhost:8000 API Docs → http://localhost:8000/docs Frontend → http://localhost:3000⚠️ 注意restart.sh中硬编码了 Python 解释器路径VENV_PYTHON/home/afei/hello_agent_venv/bin/python脚本第 14 行这是作者机器上的虚拟环境路径其他环境运行前需将其改为本机 Python 路径。4. 访问地址服务地址 游戏前端http://localhost:3000 后端 APIhttp://localhost:8000 API 文档http://localhost:8000/docs5. 手动启动可选# 启动后端 cd backend python main.py # 启动前端另开终端 cd frontend python -m http.server 3000API 接口一览后端基于 FastAPI 提供 RESTful 接口路由定义见 main.py方法路径说明POST/api/game/start开始新游戏LLM 生成人物 预生成提示POST/api/game/chat向 Agent 提问角色扮演对话POST/api/game/guess提交猜测语义匹配判断猜对返回人物图片GET/api/game/hint获取下一条提示POST/api/game/end结束当前游戏GET/api/game/status/{session_id}获取当前游戏状态所有接口统一返回 models.py 中定义的GameResponse结构class GameResponse(BaseModel): success: bool message: str data: Optional[dict] None error: Optional[str] None几个实现细节值得注意start接口在每次开局前调用_clear_log_file()截断后端日志文件——由于日志由 Python 的FileHandler持有文件描述符代码采用关闭流 → 截断文件 → 重新打开追加流的方式安全清空避免写入 NUL 字节见 main.pychat接口在游戏结束后is_game_overTrue会拒绝消息并提示请开始新游戏end接口返回完整状态含答案figure_name并从active_sessions中移除会话CORS中间件配置为allow_origins[*]允许所有来源跨域访问方便前端本地联调。前端交互与游戏规则前端是零框架的原生实现index.html定义页面结构开始页/游戏页/结果弹窗style.css负责样式app.js 用Fetch API与后端通信。核心交互逻辑startNewGame()POST/api/game/start把返回的session_id、max_questions、max_hints存入前端状态切换到游戏界面并展示欢迎语sendMessage()POST/api/game/chat将用户输入渲染为气泡并展示 Agent 回复随后用服务端返回的remaining_questions刷新统计requestHint()POST/api/game/hint展示 提示...并更新剩余提示数submitGuess()POST/api/game/guess猜对时调用endGame(true, figure_info, portrait_images)渲染画像画廊猜错则继续并同步剩余提问数。完整游戏规则如下点击「开始游戏」系统由 LLM 随机生成一位人物历史、神话、虚构、网络红人均有可能通过对话向 Agent 提问Agent 以该人物第一人称回答不会直接说出名字最多可提问10 次可使用提示3 次提示由模糊到具体随时可以提交猜测支持别名、外号等多种表达方式猜对后展示人物图片提问次数用完或主动结束则游戏结束并揭晓答案。技术栈后端FastAPI—— Web 框架含自动生成/docs交互式 API 文档hello_agents—— AI Agent 框架SimpleAgent、HelloAgentsLLM、Message、Tool基类Pydantic v2—— 数据验证Uvicorn—— ASGI 服务器Tavily Python SDK—— 搜索增强Wikipedia REST API—— 人物图片搜索前端HTML5 / CSS3 / JavaScript—— 原生实现无框架依赖Fetch API—— 与后端通信AI / LLMModelScope API—— OpenAI 兼容接口默认模型qwen-flashLLM 人物生成—— 动态随机生成避免重复LLM 语义匹配—— 判断猜测是否与答案指代同一人物日志与故障排除日志运行日志保存在logs/目录# 实时查看后端日志 tail -f logs/backend.log # 实时查看前端日志 tail -f logs/frontend.log后端日志采用自定义FileHandler挂到 root logger的方式写入刻意不用basicConfig因为它对已被 uvicorn 预配置过 handler 的 root logger 是空操作格式为时间 [级别] 日志名 - 消息并在 start 接口中做文件截断清理相关实现见 main.py。故障排除LLM 调用失败检查backend/.env中的LLM_API_KEY和LLM_BASE_URL确认 ModelScope 账号有对应模型的访问权限代码中 LLM 调用异常均有兜底人物生成走内置人物池、对话返回抱歉我现在有些恍惚请再问一次吧。游戏不会因单次调用失败而崩溃。每次生成同一个人物已通过随机种子 时间戳注入解决若仍出现请检查 LLM 模型是否支持随机性参数。Tavily 搜索不可用检查backend/.env中的TAVILY_API_KEY是否正确填写未配置时系统会自动降级使用 fallback 提示但提示质量会下降从源码可见_generate_hints()中 Tavily 与 LLM 任一环节失败都会走 fallback。端口被占用restart.sh会自动清理占用端口的进程kill_port与kill_pattern重新运行脚本即可。CORS 错误后端已配置 CORS 允许所有来源确保前端访问正确的后端端口默认 8000。总结与可扩展方向GuessWhoAmI 用不到千行代码完整示范了LLM 随机内容生成 外部搜索工具增强 无工具角色扮演 LLM 语义判断 图像检索五类 Agent 能力的组合方式且每一环都有降级兜底设计工程上相当完整。在此基础上还可以继续扩展增加难度分级把人物领域、提问次数、提示数量做成可配置的难度档位多人对战利用GameManager.cleanup_old_sessions的会话清理机制扩展为多房间同时开局的在线对战模式接入更多搜索/图像源TavilySearchTool与SearchImageTool均继承自hello_agents的Tool基类只需实现run()与get_parameters()即可低成本替换或新增工具引入语音/多模态结合 LLM 多模态能力让 Agent 用语音作答或支持图片式谜题。对想要上手hello_agents框架的开发者而言这个项目是从框架 API 到完整可玩游戏的最短路径之一值得通读其 agents.py 与 game_logic.py 后自行复刻一版。【免费下载链接】hello-agents 《从零开始构建智能体》——从零开始的智能体原理与实践教程项目地址: https://gitcode.com/GitHub_Trending/he/hello-agents创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表