怎么实现AI思考过程

unsetunset前言unsetunset

在做多Agent系统时,因为整个系统可能会经过多次Agent处理,耗时会比较高,如果不给前端展示Agent处理的过程,那么用户的体验就会非常不好,在用户的视角,你的程序可能卡死了,但其实你的Agent在背后干活以求获得好的结果。

解决方案也比较直观,就是将Agent的处理过程在前端返回出来,这也是很多产品的做法,即所谓的有一个thinking过程的展示。

本文就是实现一个这样的效果,教育目的,所以会写的经量简单。

unsetunset实现unsetunset

为了简化,我们这里就不弄多Agent系统来讲解,直接用Llamaindex构建一个基本的RAG,然后我们将RAG的过程展示为thinking过程,至于多Agent其实也一样的,然后用React来做前端。

Github: https://github.com/ayuLiao/show_llm_thinking_example

效果如下:

怎么实现AI思考过程_第1张图片

unsetunset后端技术细节unsetunset

我们定义了Message对象,每个Message对象会有关联的sub_processes对象,sub_processes对象存储着处理过程信息。

class ProcessType(str, Enum):
    THINKING = "thinking"
    SEARCHING = "searching"
    ANALYZING = "analyzing"
    GENERATING = "generating"


class SubProcess(BaseModel):
    id: str
    type: ProcessType
    status: str
    detail: str


class Message(BaseModel):
    content: str
    sub_processes: List[SubProcess]

当用户提问时,我们会先创建一个拥有回复的Message对象,一开始Message对象的content是空的,然后我们为它添加sub_process,表示开始处理了,然后在通过send_chain这个异步队列将带有sub_process的Message对象返回(添加到队列里,API那边会while True一直取,从而实现实时将状态反馈给前端)

content = ""
message = Message(content=content, sub_processes=[])

# 思考阶段
thinking_process = SubProcess(
    id=str(uuid.uuid4()),
    type=ProcessType.THINKING,
    status="running",
    detail="正在思考问题...",
)
message.sub_processes.append(thinking_process)
await send_chan.put({"data": json.dumps(message.model_dump())})
await asyncio.sleep(0.5)

thinking_process.status = "completed"
await send_chan.put({"data": json.dumps(message.model_dump())})

从上面代码可知,sub_process本身也有状态,完成了,status会设置成completed,比如我们搜索文档时,状态是SEARCHING,然后完成后,则是completed。

# 搜索阶段
search_process = SubProcess(
    id=str(uuid.uuid4()),
    type=ProcessType.SEARCHING,
    status="running",
    detail="搜索相关文档...",
)
message.sub_processes.append(search_process)
await send_chan.put({"data": json.dumps(message.model_dump())})

# 实际调用 LlamaIndex 查询
response = query_engine.query(question)

search_process.status = "completed"
await send_chan.put({"data": json.dumps(message.model_dump())})

然后,我们流式返回,真正的结果,会添加到message.content中。

# 生成回答阶段
generating_process = SubProcess(
    id=str(uuid.uuid4()),
    type=ProcessType.GENERATING,
    status="running",
    detail="生成回答中...",
)
message.sub_processes.append(generating_process)
await send_chan.put({"data": json.dumps(message.model_dump())})

# 逐字输出回答
for word in str(response).split():
    content += word + " "
    message.content = content
    await send_chan.put({"data": json.dumps(message.model_dump())})
    await asyncio.sleep(0.1)

generating_process.status = "completed"
await send_chan.put({"data": json.dumps(message.model_dump())})

await send_chan.put(None)

整个流程非常直观。

如果你是多Agent,那么也是先构建一个Message对象,然后一直将Message对象返回,只是Message对象里的sub_processes随着Agent处理在变化,然后返回给前端。

unsetunset前端技术细节unsetunset

前端就没什么好讲的,创建好React项目后,修改App.tsx,当用户点击提交后,一直监听后端返回的流式信息,相关代码如下:

const handleSubmit = async (e: React.FormEvent) => {
  e.preventDefault();
  if (!question.trim() || isLoading) return;

  setIsLoading(true);
  setMessage({ content: "", sub_processes: [] });

  const eventSource = new EventSource(
    `http://localhost:8000/chat?question=${encodeURIComponent(question)}`
  );

  eventSource.onmessage = (event) => {
    console.log("Received event:", event.data); // 调试日志
    try {
      const newMessage = JSON.parse(event.data);
      setMessage(newMessage);
    } catch (error) {
      console.error("Error parsing message:", error);
    }
  };

  eventSource.onerror = (error) => {
    console.error("EventSource error:", error); // 调试日志
    eventSource.close();
    setIsLoading(false);
  };

  // 添加onopen处理
  eventSource.onopen = () => {
    console.log("EventSource connected"); // 调试日志
  };

  // 清理函数
  return () => {
    eventSource.close();
    setIsLoading(false);
  };
};

然后页面上,展示sub_processes就实现了展示thinking过程的效果。

 
    {message.sub_processes.map((proc) => (      
                  {proc.status === "running" ? "⏳" : "✅"}                 {proc.detail}      
    ))}  
 
{message.content || "等待回答..."}

unsetunset尾部unsetunset

最近团队扩张招人,我们需要:

  • 海外运营(了解SEO、海外社媒运营、英文读写过关的)

  • Python开发(了解RAG、Agent框架、基本后端)

  • React开发(了解Nextjs)

在广州的同学,可以给我发简历,本司不加班、扁平化,全员配MacOS+2K显示器,报销Cursor等各种AI提效产品,能了解到最新的AI技术的变化,有兴趣就来一起开发能落地的多Agent系统吧。

你可能感兴趣的:(状态模式)