Skip to content

Latest commit

 

History

History
164 lines (137 loc) · 8.45 KB

File metadata and controls

164 lines (137 loc) · 8.45 KB

核心思路整理

项目核心是创建一个由AI驱动的双角色(SWK 和 ADA)对话系统,目标是引导用户在一个预设的剧情框架下做出关键选择。其关键特性如下:

  1. 静态世界观:存在一个固定的“故事背景”,以及两个性格、目标、说话风格迥异的NPC:“SWK”和“ADA”。这些是整个对话系统的基础上下文。
  2. 动态引导:对话并非完全开放,而是有一个明确的“剧情设定”,即引导用户最终做出“追随SWK”或“追随ADA”的选择。NPC的对话内容需要服务于这个目标。
  3. 智能输入处理:系统需要具备两种智能校验能力:
    • 相关性校验:判断用户的输入是否与当前对话主题相关。如果无关,则主动引导用户回来。
    • 歧义校验:判断用户的输入是否模糊不清。如果存在歧义,则不直接回答,而是生成2-4个澄清选项,让用户选择,从而确保对话的准确性。
  4. 状态化对话:整个对话过程需要记录上下文(聊天记录),以便AI能做出连贯的回应。

技术实现流程(基于Python, FastAPI, LangGraph)

整个流程可以看作一个由LangGraph构建的“智能对话图”:

第零步:服务启动与初始化

  1. 当后端服务启动时,从配置文件(如 config/story.json, config/characters.json)中加载故事背景、剧情设定以及SWK和ADA的详细角色设定(性格、目标、说话风格等)到内存中。

第一步:接收用户输入 (API Endpoint)

  1. 前端通过调用 POST /chat/send API,将用户的输入内容和会话ID(session_id)发送到后端。

第二步:进入LangGraph工作流

  1. 后端根据 session_id 找到或创建一个新的对话状态(State),其中包含聊天记录、角色设定等信息。
  2. 将用户的新输入添加到状态中,启动LangGraph工作流。

第三步:相关性判断节点 (Relevance Check Node)

  1. 这是图的第一个逻辑节点。
  2. 它会调用LLM,并提供一个简单的提示词,例如:

    “背景:[故事背景]。当前对话:[最近几轮对话]。用户最新输入:‘{user_input}’。请判断此输入是否与当前对话主题相关。请只回答‘相关’或‘不相关’。”

  3. 此节点的结果将决定图的走向。这是一个条件路由 (Conditional Edge)

第四步:路由选择

  • 如果结果是“不相关”
    • 工作流转向引导节点 (Guidance Node)
    • 此节点生成一句提示性的话术,如“我们好像聊远了,还是继续刚才的话题吧。”或者“现在专注于解决眼前的问题更重要。”
    • 将这句话作为AI的回应,工作流结束,返回给前端。
  • 如果结果是“相关”
    • 工作流继续前进到下一步。

第五步:歧义判断节点 (Ambiguity Check Node)

  1. 这是图的第二个逻辑节点。
  2. 它会调用LLM,提示词会更复杂一些,例如:

    “在以下对话情境中,分析用户输入‘{user_input}’是否存在多种可能的解释或歧义。如果存在,请生成2-4个最有可能的、简洁的澄清选项(例如‘你的意思是指A吗?’)。如果输入清晰明确,则返回一个空列表。请以JSON列表格式输出。”

  3. 此节点的输出同样会触发一个条件路由

第六步:再次路由选择

  • 如果返回的澄清选项列表不为空
    • 工作流结束。
    • API直接将这个选项列表返回给前端。前端需要将这些选项展示给用户点击。用户的下一次请求将是 POST /chat/clarify,带着他选择的那个选项文本。
  • 如果返回的列表为空
    • 用户的输入被认为是清晰的,工作流进入最终的核心对话生成环节。

第七步:核心对话生成节点 (Dialogue Generation Node)

  1. 这是最重要的节点,它聚合了所有上下文信息来调用LLM。
  2. 提示词将包含:
    • 故事背景核心剧情设定
    • SWK的角色设定(性格、目标、对用户的看法等)。
    • ADA的角色设定
    • 完整的对话历史
    • 用户(已确认清晰的)输入
    • 核心指令:“请你同时扮演SWK和ADA,根据各自的角色设定和当前对话情境,对用户的输入做出回应。你们的对话需要潜移默化地引导用户思考并最终选择追随谁。请以JSON格式返回,包含SWK和ADA各自的回复。”
  3. LLM生成SWK和ADA的回应。

第八步:更新状态并返回

  1. 将用户的输入以及AI生成的回应追加到会话的聊天记录中。
  2. 将生成的对话内容通过API返回给前端。工作流本次执行完毕。

文件结构与说明

一个清晰的项目结构能让开发和维护更简单。

/your_project
|
├── main.py                 # FastAPI应用主入口,定义API接口
|
├── config/
|   ├── story.json          # 存放共同的故事背景和核心剧情设定
|   └── characters.json     # 存放SWK和ADA的详细角色设定(性格、MBTI、目标、风格等)
|
├── prompts/
|   ├── relevance_check.txt # 相关性检查的提示词模板
|   ├── ambiguity_check.txt # 歧义检查的提示词模板
|   └── dialogue_gen.txt    # 核心对话生成的提示词模板
|
├── services/
|   └── chat_service.py     # 核心业务逻辑,LangGraph图的定义和构建就在这里
|
└── models.py               # Pydantic模型,定义API的请求体和响应体结构
  • main.py: 负责启动FastAPI服务,定义/chat/send等API端点,并调用chat_service中的功能。
  • config/*.json: 将设定数据化,便于程序读取和修改,而不用硬编码在代码里。
  • prompts/*.txt: 将复杂的提示词与业务逻辑代码分离,便于调试和优化Prompt。
  • services/chat_service.py: 项目的大脑。这里会初始化LangGraph,定义图中所有的节点(函数)和边(路由逻辑)。
  • models.py: 定义数据契约。例如,ChatRequest模型规定了前端发来的请求必须包含哪些字段,ChatResponse模型规定了后端返回的数据格式。

API 设计

您至少需要以下两个API端点:


1. 发送对话 (Send Dialogue)

  • Endpoint: POST /chat/send
  • 作用: 用户输入新对话,启动主要的对话处理流程。
  • 请求体 (Request Body):
    {
      "session_id": "a_unique_session_identifier_string",
      "text": "用户输入的对话内容"
    }
  • 成功响应 (Success Response - 200 OK):
    • 情况A:正常对话回复
      {
        "type": "dialogue",
        "data": [
          { "character": "SWK", "text": "孙悟空的回应..." },
          { "character": "ADA", "text": "艾达的回应..." }
        ]
      }
    • 情况B:需要用户澄清
      {
        "type": "clarification",
        "data": [
          "你的意思是指...吗?",
          "你是想问关于...的事情吗?",
          "或者你是想表达...?"
        ]
      }
    • 情况C:用户输入不相关
      {
        "type": "guidance",
        "data": {
          "text": "我们还是继续刚才的话题吧。"
        }
      }

2. 选择澄清选项 (Select Clarification)

这个API是可选的,但能让逻辑更清晰。当用户点击了澄清选项后,前端调用此接口,后端将其视为用户“真正想说的话”来继续处理。

  • Endpoint: POST /chat/clarify
  • 作用: 用户从澄清选项中选择一个,作为他/她的明确输入。
  • 请求体 (Request Body):
    {
      "session_id": "a_unique_session_identifier_string",
      "text": "用户选择的那个澄清选项的文本"
    }
  • 逻辑: 这个API的后端逻辑会跳过相关性和歧义检查,直接将text内容送入核心对话生成节点,然后返回正常的对话回复。

这个方案为您提供了一个从概念到具体代码实现的完整蓝图,您可以基于此开始搭建您的AI后端了。