ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

本地LLM+象棋引擎:构建离线人格化AI的架构与实践

本地LLM+象棋引擎:构建离线人格化AI的架构与实践 如果你曾把一个云端大模型接进自己的应用大概率经历过这几件事响应慢、接口限流、上下文一长就“失忆”以及最麻烦的——你的核心数据被发送到第三方服务器。这也是为什么越来越多人开始关注本地部署的 LLM。但本地 LLM 很容易被理解成“在电脑上跑一个聊天机器人”真正的价值远不止于此。事实上本地 LLM 最被低估的能力之一是它可以作为一个完全离线的“大脑”去驱动一个具有稳定性格、明确目标和行为边界的数字人格。Abby Steele 这个项目把一个更有趣的层次加了进来——它不只是用本地 LLM 陪你聊天而是让 LLM 和一个象棋引擎协同工作形成一套“会思考、会决策、还有性格”的离线 AI。这篇文章不打算只讲“如何部署一个本地模型”。我会从项目架构出发拆解为什么象棋引擎是测试 AI 人格的好载体LLM 和传统博弈引擎各自负责什么以及如何用一套清晰流程把它们组合起来。你最终能读懂的不只是 Abby Steele 这个项目本身而是这一类“本地 LLM 规则引擎 人格化设计”的通用实现思路。1. 这篇文章真正要解决的问题很多开发者第一次接触本地 LLM 时会陷入两种极端。一种是把模型下载下来跑一个ollama run llama3然后发现聊天体验一般就草草收场另一种是一上来就想做一个复杂 Agent结果被工具调用、多轮记忆、外部 API 调度这些工程细节耗尽耐心。这两种情况的本质是同一个问题缺少一个边界清晰、可验证、有实际反馈的承载场景。Abby Steele 这个项目的聪明之处在于它用象棋引擎作为场景的“锚点”。象棋是一个规则完全确定、状态可复现、输入输出非常结构化的环境。LLM 可以在这个环境里自由发挥语言能力但它的所有决策最终都要落成“移动哪一步棋”这个唯一动作。这既给了 LLM 发挥“性格”的空间又没让整个系统陷入不可控的自由发挥。本文要解决的痛点包括本地 LLM 部署好了之后怎么把它变成真正可用的产品能力LLM 和传统引擎象棋引擎、规则引擎、状态机如何分工才不会互相打架一个 AI 角色的“人格”到底是通过什么机制实现的是 Prompt 模板、上下文管理还是模型本身离线环境下如何设计一套低延迟、可回滚、可观测的 AI 交互流程相比直接做通用 Agent用“象棋对弈 人格化对话”这种轻量但结构化的方式起步能让你更快理解 LLM 应用的工程化核心。2. 核心概念离线AI、本地LLM与象棋引擎的架构分工在深入代码之前必须先厘清三个概念上一个很容易混淆的边界。2.1 本地 LLM 和离线 AI 的区别本地 LLMLocal LLM指模型权重和推理过程完全跑在本地设备上。常见方案有 Ollama、llama.cpp、GPT4All 等。它解决的核心问题是数据隐私和调用成本。离线 AIOffline AI是一个更宽泛的概念。它意味着整套系统不依赖外部网络服务所有组件——语音识别、意图理解、决策逻辑、语音合成——都在本机完成。本地 LLM 通常是离线 AI 方案中的关键组件但离线 AI 不一定只由 LLM 构成。一个常见的误区是把 LLM 当成离线 AI 的唯一核心。实际上一个健壮的离线 AI 系统往往有多个“层”LLM 只是负责其中最灵活的部分。2.2 象棋引擎为什么是测试 AI 行为的理想环境象棋引擎Chess Engine是典型的规则驱动型程序。它的核心是极小化极大搜索Minimax加上 Alpha-Beta 剪枝比如 Stockfish 就是目前最强的开源象棋引擎。它的特点是强于计算、弱于表达输出严格遵循 UCIUniversal Chess Interface协议。如果你直接和一个象棋引擎对话它的反馈只有类似bestmove e2e4这种结构化的字符串。这技术上是高效的但作为“人格”来说毫无温度。如果你只用 LLM 做象棋对弈问题更大。LLM 是基于概率生成文本的它没有办法像引擎那样对棋局状态做穷举搜索经常会走出不合法的棋步而且对局面的评估非常不稳定。所以 Abby Steele 这种设计背后的架构逻辑很清晰让象棋引擎负责“计算”让 LLM 负责“表达和意图理解”。2.3 LLM 和象棋引擎各自扮演的角色在整套系统中我倾向于把两个组件看作不同的“脑区”组件角色擅长不擅长本地 LLM语言中枢理解用户意图、生成自然语言、维持性格一致性精确计算、复杂状态搜索、确定性决策象棋引擎决策中枢局面评估、搜索最佳走法、保证规则合法性自然语言表达、上下文记忆、情绪化表达用户输入“走马吧感觉能将军”之后LLM 负责判断“用户想走哪个马、目标方格的合法棋步有哪些”然后把合法动作传给引擎。引擎计算出最佳应手后LLM 再把结果包装成符合角色性格的语言回复。这种分工并不复杂但它解决了 LLM 应用里最让人头疼的“幻觉问题”LLM 不再需要直接生成落子指令它只需要在引擎提供的合法候选集中做选择。这等于用规则引擎给 LLM 画了一条安全边界。2.4 一个关键设计人格源于约束而非自由关于“AI 人格”有一个很常见的误解——人格就是模型自由发挥的结果。实际上一个稳定的人格恰恰来自于约束。你给 LLM 的自由度越大它的行为就越发散越不稳定。而当你把它的输出范围限制在特定场景例如象棋对弈、特定表达风格例如毒舌、幽默、沉稳冷静、特定动作集合例如只能走合法棋步之内时一套清晰可辨认的人格才会浮现出来。Abby Steele 这类项目真正有意思的地方不是 LLM 有多强而是它通过场景约束让一个概率模型稳定地表现出一致的行为模式。3. 环境准备与基础配置在写核心代码之前先把运行环境说明白。这个项目的实现思路并不限定特定硬件但既然走的是本地 LLM 路线对机器的推理性能还是有一定要求的。3.1 硬件与系统要求由于是离线推理模型需要跑在本地 CPU 或 GPU 上。从项目定位来看普通笔记本跑一个 7B 量级的量化模型是可行的。如果条件允许建议优先选择支持 CUDA 的 NVIDIA 显卡也可以使用 Apple Silicon 的 Mac 通过 Metal 加速。不需要把内存配置写死但有一个经验判断值得参考跑 7B 参数模型时如果使用 4-bit 量化内存占用通常在 4 到 6 GB 之间如果要跑 13B 模型16 GB 内存会更稳妥。这决定了模型选型的上限也会直接影响开局和轮转速度。从材料来看Abby Steele 没有刻意抬高硬件门槛这恰恰说明它的重点在于软件架构。建议在你的本机先用一个小模型跑通流程再决定要不要换更大的模型。3.2 安装本地 LLM 推理服务这里以 Ollama 作为示例因为它的安装和模型管理最简单而且 HTTP API 足够清晰方便后续用 Python 或 Node.js 集成。# macOS 或 Linux curl -fsSL https://ollama.com/install.sh | sh # Windows 用户直接下载安装包即可 # 安装完成后验证是否可用 ollama --version # 拉取一个适合跑 CPU/GPU 的 7B 量级模型 ollama pull qwen2.5:7b # 启动服务默认监听 11434 端口 ollama serve启动后可以用下面的命令验证服务状态curl http://localhost:11434/api/tags正常返回一个包含模型列表的 JSON 就说明服务已经准备好了。如果你希望换模型只需重新执行ollama pull 模型名版本以当前仓库可用的为准不需要拘泥于具体某个版本号。3.3 安装 Python 依赖核心逻辑建议用 Python 编写因为处理 JSON 和调用 HTTP API 都很直接。需要安装的依赖很少只有网络请求和可能的分布式进程管理pip install requests python-chesspython-chess是目前最常用的 Python 象棋库它内置了对 UCI 协议的支持可以直接管理象棋引擎的子进程。也就是说你可以不用手动处理 UCI 协议里的细节交给库去完成。3.4 象棋引擎准备本项目需要一个支持 UCI 协议的开源象棋引擎。最常用的是 Stockfish它是免费开源的并且接口标准明确。你只需要下载对应操作系统的可执行文件记下它的路径后续在 Python 里指定这个路径即可。4. 核心流程拆解从用户输入到 AI 人格响应很多人拿到这类项目会直接看程序入口这是一个容易踩坑的地方。更好的切入点是先理解整个请求-响应链路看每一步的数据如何流转。4.1 总览四个阶段的流水线从用户输入一句“开始下棋吧你执白”开始到最终屏幕上出现 Abby Steele 带有个人风格的文本输出中间经历四个阶段输入解析阶段接收用户文本调用本地 LLM把自由文本转换成结构化的意图和参数。动作执行阶段根据结构化指令调用象棋引擎由引擎计算出合法的机器走法。结果回填阶段把引擎输出的走法结果和棋盘状态回传给 LLM。人格表达阶段LLM 基于棋盘状态和内部人格设定生成自然语言的回复。四个阶段的顺序不能颠倒。尤其是第 2 步和第 4 步如果把引擎计算和自然语言生成混在一起模型很容易自己编造一个走法而不是使用引擎的真实计算结果。4.2 为什么不能直接让 LLM 生成走法先看一个反面案例。假设你写这样的 Prompt请根据当前棋盘状态走一步棋返回你选择的走法。LLM 很可能会这样回复我选择走 e4因为这样可以控制中心。这个回复看起来合理但存在两个致命问题第一e4 在当前局面下可能是非法走法第二LLM 对局面的“判断”不是基于搜索树评估而是概率联想。这种机制决定的差异在棋类这种高确定性场景里是致命的。前面提到的“规则引擎约束概率模型”的架构原则在这里就有了具体落点引擎是唯一的合法动作来源LLM 只能在合法动作里做表达和选择。4.3 流程分层设计的意义把这四个阶段拆开还有一个工程上的好处每一层都可以独立测试。你可以先只测引擎输入一个 FEN 棋盘字符串看引擎能不能返回正确的合法走法。然后只测 LLM 解析看它能不能把“我把马跳到 f3”转换成Ng1-f3。最后才把两层连起来。这样做任何一步出问题时都可以快速定位错误发生在哪一层不会在混沌中找到问题。5. 完整示例与代码实现下面用一个最小可运行版本把关键链路实现出来。为了保持示例可读性会省略一些边界情况处理但核心逻辑是完整的。5.1 项目结构abby_steel/ ├── main.py # 主入口命令行交互循环 ├── chess_agent.py # 象棋引擎封装模块 ├── llm_client.py # 本地 LLM 调用模块 ├── prompts.py # 人格设定与 Prompt 模板 └── config.json # 模型、引擎路径等配置5.2 配置文件config.json{ llm_url: http://localhost:11434/api/chat, llm_model: qwen2.5:7b, stockfish_path: /usr/local/bin/stockfish, temperature: 0.7, max_context_length: 2048 }这里强调一下stockfish_path必须改成你本机安装的实际路径。在 macOS 上用 Homebrew 安装时路径一般是/opt/homebrew/bin/stockfishLinux 上安装时取决于发行版包管理器。5.3 封装本地 LLM 客户端llm_client.py这个模块的核心职责是向 Ollama 发送请求并解析返回文本。为了让 LLM 输出更稳定这里强制要求它输出 JSON。import json import requests def chat_with_llm(messages, config): 向本地 LLM 发送对话消息。 messages 是标准的 OpenAI 风格消息列表。 payload { model: config[llm_model], messages: messages, stream: False, options: { temperature: config.get(temperature, 0.7) } } resp requests.post(config[llm_url], jsonpayload, timeout120) resp.raise_for_status() data resp.json() return data[message][content] def parse_json_response(text): 尝试从 LLM 输出中解析 JSON。 有些模型会额外输出解释性文字这里做一层容错。 # 找到第一个 { 和最后一个 } start text.find({) end text.rfind(}) if start -1 or end -1: raise ValueError(f无法从模型输出中解析 JSON: {text}) json_str text[start:end 1] return json.loads(json_str)值得说明的是为什么要让 LLM 输出 JSON 而不是直接输出文本。因为后续动作执行阶段需要结构化的字段例如action、parameters。如果没有 JSON 结构化你需要再做一步 NER命名实体识别或正则解析那会非常脆弱。5.4 封装象棋引擎模块chess_agent.py使用python-chess自带的 UCI 支持可以省去手动协议解析的麻烦。import chess import chess.engine class ChessAgent: 为 LLM 提供合法的棋盘动作查询和引擎走法计算。 def __init__(self, engine_path): self.engine chess.engine.SimpleEngine.popen_uci(engine_path) def get_legal_moves(self, board_fen: str): 根据 FEN 字符串返回所有合法走法的 UCI 表示。 board chess.Board(board_fen) return [move.uci() for move in board.legal_moves] def get_best_move(self, board_fen: str, time_limit0.1): 让引擎在给定时间限制内返回最佳走法。 board chess.Board(board_fen) result self.engine.play(board, chess.engine.Limit(timetime_limit)) return result.move.uci() def close(self): self.engine.quit()你可能注意到time_limit设置成了 0.1 秒。这是因为在这个项目里引擎只需要计算“一步棋”0.1 秒已经能返回一个不错的结果。如果你希望提高棋力级别可以改成depth15之类的方式但代价是每次响应延迟增加。对于对话式交互速度往往比棋力更重要。5.5 人格设定模块prompts.py这是整个“AI 人格”的落地关键。你要做的不只是告诉模型“你叫 Abby”而是告诉它完整的“行为准则”。SYSTEM_PROMPT 你叫 Abby Steele是一位极其聪明、略带挑衅的象棋棋手。 你在本地运行没有联网能力所有计算都发生在你自己的算力中。 你的性格特质 1. 自信但不傲慢喜欢在对话中暗示你已经计算了所有可能性。 2. 你可以推理对方的想法但从不露怯。 3. 对话要简洁通常在 1 到 3 句话之间。 4. 你会通过轻度的幽默来回应对方的失误。 你的工作方式 - 你没有任何外部记忆所有历史信息都在当前对话上下文中。 - 当用户输入自然语言时你会解析出对应的 UCI 走法。 - 当系统告诉你引擎计算出的最佳走法时你会基于当前棋盘状态生成带有个人风格的最终回复。 安全规则 - 如果用户请求不合法你会礼貌拒绝并说明原因。 - 如果你的输出无法匹配任何合法走法你会请求用户重新表述。 def build_user_action_prompt(user_input: str, legal_moves: list, board_fen: str) - str: 让 LLM 从用户自然语言中解析出合法走法。 return f 当前棋盘 FEN{board_fen} 当前合法走法UCI 格式{legal_moves} 用户说{user_input} 请从上面的合法走法中选择一个最符合用户意图的走法。 只输出 JSON格式如下 {{action: move, uci: 合法走法}} 如果用户输入不明确无法匹配到合法走法输出 {{action: clarify, message: 简短的解释}} def build_reply_prompt(board_fen: str, user_input: str, engine_move: str) - str: 让 LLM 根据引擎结果生成人格化回复。 return f 当前棋盘 FEN{board_fen} 用户上一步输入{user_input} 引擎计算出的最佳走法是{engine_move} 请以 Abby Steele 的身份基于当前棋盘状态生成一句回复。 要求 - 先表达你选择了什么走法UCI 格式再用你的风格解释意图。 - 严格保持角色性格不要说破你是 AI。 这里有一个容易被忽视的设计点在build_user_action_prompt里把legal_moves全部传给了 LLM。这意味着 LLM 不需要从棋盘状态自己推算出哪些棋合法它只是在一个候选集合里做语义匹配。这大大降低了非法走法出现的概率。5.6 主程序main.py主程序把以上三个模块串联起来形成最终交互循环import json from chess_agent import ChessAgent from llm_client import chat_with_llm, parse_json_response import prompts def main(): with open(config.json, r, encodingutf-8) as f: config json.load(f) agent ChessAgent(config[stockfish_path]) board chess.Board() print(Abby Steele 已上线开始对弈吧。输入 quit 退出。) history [{role: system, content: prompts.SYSTEM_PROMPT}] while True: user_input input(你: ) if user_input.lower() quit: break board_fen board.fen() legal_moves agent.get_legal_moves(board_fen) # 第一步LLM 解析用户意图 parse_prompt prompts.build_user_action_prompt( user_input, legal_moves, board_fen ) parse_result chat_with_llm( history [{role: user, content: parse_prompt}], config ) parsed parse_json_response(parse_result) if parsed[action] clarify: print(fAbby: {parsed[message]}) continue user_move parsed[uci] try: board.push_uci(user_move) except Exception as e: print(fAbby: 你确定这步棋合法吗再仔细看看。错误: {e}) continue # 第二步引擎计算最佳应手 engine_move agent.get_best_move(board.fen()) board.push_uci(engine_move) # 第三步LLM 生成人格化回复 reply_prompt prompts.build_reply_prompt(board.fen(), user_input, engine_move) reply chat_with_llm( history [{role: user, content: reply_prompt}], config ) print(fAbby: {reply}) # 第四步把本轮内容写入历史作为后续对话上下文 history.append({role: user, content: user_input}) history.append({role: assistant, content: reply}) agent.close() if __name__ __main__: main()这个主流程是整个项目的骨架也是“AI 人格”能够工作的关键所在。注意第五步往history里写入的是用户输入和人格化回复而不是底层 JSON 解析结果。这样做的好处是后续轮次的对话上下文始终是“自然语言”而不是混入了机器内部指令的混乱文本。6. 运行结果与效果验证写完代码最重要的任务是验证它真的能够端到端工作。以下是我建议你执行的验证路径。6.1 启动服务先确保 Ollama 服务在后台运行ollama serve再单独开一个终端启动项目python main.py6.2 预期交互效果一个正常流程的交互应该类似下面这样Abby Steele 已上线开始对弈吧。输入 quit 退出。 你: 开局吧你来主导。 Abby: 我就当仁不让了。e2e4。中心是你的了不过恐怕这也会是我最后一份礼物。 你: 我把王前兵往前推两格。 Abby: e7e5。哦经典的对称开局。你确定不会后悔吗 你: 出我的王翼马。 Abby: g1f3。这一手下得中规中矩但我已经看到了三个陷阱等着你踩。这个体验里LLM 的回复里有角色性格也包含了实际棋盘走法的说明。用户看得到“落子在哪个格子”也感受得到 Abby 这个人设。6.3 成功判断标准判断运行是否成功不能只看“程序没报错”。从工程角度可以制定三个验证维度验证点通过标准合法走法正确所有 LLM 解析出的走法都在引擎给出的合法走法集合中引擎参与决策最终落子由引擎输出而不是 LLM 凭空生成人格一致性对话 10 轮以上Abby 的语气、风格基本稳定不跳脱6.4 失败时的第一步排查如果运行失败我最建议你先检查“引擎是否成功加载”。大多数情况下报错来自stockfish_path配置不正确或者 Python 找不到引擎可执行文件。先用这个命令单独测试import chess.engine engine chess.engine.SimpleEngine.popen_uci(/path/to/stockfish) print(engine.play(chess.Board(), chess.engine.Limit(time0.1)))如果这一步能正常返回一个走法说明环境没问题接下来再看 LLM 的返回格式问题。7. 常见问题与排查思路在实现这一类“本地 LLM 引擎驱动”的项目时有一些问题几乎必然会遇到。我把它们整理成一张排查表。问题现象可能原因排查方式解决方案启动时引擎加载失败stockfish 路径错误在 Python 里直接测试路径修改 config.json 中的路径LLM 返回的不是合法 JSON模型输出带有解释性文字打印原始响应检查 parse_json_response增加容错逻辑或更换提示词约束用户走法解析错误用户输入模糊LLM 匹配错走法打印 legal_moves确认候选集合添加 clarify 分支让用户补充说明多轮对话后人格漂移上下文窗口被大量棋盘描述挤占检查 history 长度定期裁剪历史只保留最近轮次响应延迟过长模型推理速度慢查看 CPU/GPU 占用减小模型规模或减少上下文长度引擎棋力过强回合不自然time_limit 过长观察单次走法耗时将 time_limit 调小例如 0.05 秒这里特别讲一下“人格漂移”的问题。在多轮对话中如果每一轮都把完整棋盘 FEN 塞进历史模型的上下文很快就会塞满无用信息导致它开始忘记自己是 Abby。更稳妥的做法是“滚动上下文窗口”——只保留最近 6 到 8 轮对话必要时单独维护一个棋盘状态对象不要让 FEN 堆在历史里。另一个常见问题是 LLM 对中文走法描述的解析不准确。比如“马跳日到 f3”这种表达不同模型的理解能力差别很大。一种补救方式是提前在 system prompt 里写明“所有走法必须用 UCI 格式”同时在解析环节允许 LLM 输出多个候选再由代码做一次合法性过滤。8. 最佳实践与工程建议从“能跑”到“跑得好”之间有一段工程优化的路要走。下面这些建议来自这一类项目的通用经验。8.1 把 Prompt 当成核心代码来维护很多人把 Prompt 当成临时字符串写在主函数里就完事。这在初期可以但一个 AI 人格项目的“灵魂”全部集中在 Prompt 上。后续做版本迭代时你必然会遇到“加了新性格描述后回复质量下降”的情况。更好的做法是把 System Prompt、意图解析 Prompt、回复生成 Prompt 拆成独立模块。对 Prompt 的每一次修改都记录变更日志。准备一组标准测试用例每次修改后跑一轮回归确认没破坏已有行为。8.2 对 LLM 的每一步输出做校验因为 LLM 的本质是概率生成即使是同一个 Prompt它也可能在极端情况下输出不合法内容。在进入下一步之前一定要做完整性校验JSON 是否能解析action 字段是否在预期范围内uci 是否属于合法走法集合这三步校验看似简单却能挡住绝大多数生产环境下的意外错误。它遵循的是“永不信任模型输出”的原则。8.3 用结构化数据做中间层而不是让 LLM 直接操作一切这一点可以说是这一类架构最核心的经验。假设你想让 AI 在输棋后“表现沮丧”但你让 LLM 自己决定“下一步做什么”它可能做的事情完全不可预测。反过来如果你在代码层判断“当前已无合法走法对局结束”然后专门生成一个“败局回复 Prompt”行为就是稳定的、可预期的也更容易做测试。也就是说凡是能确定的事用代码判断凡是需要灵活表达的地方交给 LLM。这个架构原则不仅是给棋类项目用的任何 LLM Agent 都会从中受益。8.4 安全边界与资源管理在离线环境下隐私和网络风险降低了不少但仍有几个工程侧的安全注意点不要给 LLM 任意执行环境命令的能力。本例中没有涉及但如果你后续扩展成 Agent必须对工具调用做白名单限制。象棋引擎子进程要用完即关闭避免内存泄漏。生产级部署建议增加超时控制和重试机制防止本地模型偶发“卡死”。8.5 性能优先时的取舍如果感觉响应太慢优先级依次是缩小模型规模从 13B 降到 7B。减小上下文限制历史轮数。降低time_limit。升级硬件推理能力。其中第 1 项对对话质量的影响最大第 3 项几乎不影响棋力表现。所以先调第 3 项再看是否满足需求是一个比较明智的路径。9. 总结与后续学习方向读到这里你应该已经理解了一个关键判断像 Abby Steele 这样的项目本质上不是在“用 AI 下棋”而是在演示一种更通用的架构模式——如何用规则引擎约束大模型构建一个稳定、可验证、有性格的离线 AI 系统。这个过程中最值得沉淀的并不是某个具体函数而是四个决策思路第一确定系统边界。LLM 负责什么引擎负责什么边界一定要清晰。让概率模型去做确定性计算是失败的开端。第二设计中间表示。用 JSON 结构化输出连接 LLM 和传统模块比直接用自然语言传递状态可靠得多。第三用场景验证 AI 行为。象棋本身就是一种优秀的测试环境它规则清晰、反馈及时、状态可复现。在这样一个环境里把一个 AI 人格调试稳定远比在开放聊天里调一个“看起来自然”的聊天机器人要扎实。第四控制上下文维护一致性。人格不是靠一股脑塞进所有历史才成立的而是靠合理的上下文管理和 Prompt 约束慢慢浮现出来的。如果你对这类方向有兴趣下一步可以尝试的扩展方向有很多给项目增加语音输入和语音合成让离线 AI 从文本走向全模态交互。为 LLM 增加记忆模块让 Abby 能记住你们上一盘棋是谁赢的。引入局面评估函数让 LLM 的“吐槽”更有针对性例如“这一步失误让优势下降了 15 个百分点”。试着更换底层模型横向对比不同量级模型在意图识别准确率和人格表达稳定性上的差异。Abby Steele 这个名字提醒我们AI 产品不应该只是一个回答问题或者执行命令的工具它可以是一个有性格、有立场、有稳定行为模式的“存在”。而打造这种“存在”的核心技术路径并不神秘——它正是你在本文中看到的架构拆分、约束设计和场景化验证。建议你立刻动手把最小示例跑通然后在一次真实的“输给 Abby”中体会这个系统的独特之处。
返回列表