Python 服务来实现多智能体协作
在 PHP ThinkPHP 6 (TP6) 框架中,我们通常需要结合 CrewAI 的 Python 服务来实现多智能体协作。因为 CrewAI 原生是 Python 框架,最推荐的架构是:Python 负责 CrewAI 的智能体编排(后端算力),ThinkPHP 6 负责 Web 接口、数据持久化和前端交互。
以下为您提供一套完整的 TP6 + CrewAI 异步任务处理的初始化代码模版。
第一步:Python 侧(构建 CrewAI API 服务)
首先,在 Python 中使用 FastAPI 将 CrewAI 封装为一个 API 接口,供 TP6 调用。
python
# filename: main.py
from fastapi import FastAPI, BackgroundTasks
from pydantic import BaseModel
from crewai import Agent, Task, Crew
app = FastAPI()
class CrewRequest(BaseModel):
topic: str
callback_url: str # TP6的接收结果回调地址
def run_crew_async(topic: str, callback_url: str):
import requests
# 1. 定义智能体
researcher = Agent(
role='高级研究员',
goal=f'围绕 {topic} 搜集最新、最深度的数据和见解',
backstory='你是一名资深行业分析师,擅长从海量信息中抽丝剥茧。',
verbose=True
)
# 2. 定义任务
task = Task(
description=f'分析 {topic} 的现状、面临的挑战及未来趋势。',
expected_output='一份结构清晰的Markdown格式行业分析简报。',
agent=researcher
)
# 3. 组装团队并运行
crew = Crew(agents=[researcher], tasks=[task])
result = crew.kickoff()
# 4. 异步回调把结果传给 TP6
requests.post(callback_url, json={"topic": topic, "result": str(result), "status": "success"})
@app.post("/api/v1/crew/research")
def start_research(data: CrewRequest, background_tasks: BackgroundTasks):
# 使用后台任务异步执行,防止 HTTP 请求超时
background_tasks.add_task(run_crew_async, data.topic, data.callback_url)
return {"code": 200, "msg": "CrewAI 任务已启动,正在后台处理..."}
请谨慎使用此类代码。
第二步:ThinkPHP 6 侧(编写控制器与接口)
在 TP6 中,我们需要写两个核心方法:一个用来触发任务(呼叫 Python),另一个用来接收回调(保存 AI 算出的结果)。
1. 创建控制器
在 TP6 项目中执行命令:php think make:controller AiAgent
2. 编写控制器代码 (app\controller\AiAgent.php)
php
<?php
namespace app\controller;
use app\BaseController;
use think\facade\Http;
use think\facade\Log;
use think\facade\Db;
class AiAgent extends BaseController
{
// Python CrewAI 服务的 API 地址
private $pythonServiceUrl = 'http://127.0.0';
/**
* 发起 CrewAI 异步研究任务
* URL: http://your-domain/ai_agent/createTask
*/
public function createTask()
{
// 1. 接收前端或用户输入的关键词
$topic = $this->request->param('topic', '人工智能在2026年的发展趋势');
// 2. 动态生成 TP6 本地的回调地址 (请确保 Python 服务器能访问到此地址)
$callbackUrl = url('ai_agent/callback')->suffix(false)->domain(true)->build();
try {
// 3. 使用 TP6 自带的 Http 类向 Python 发送请求
$response = Http::post($this->pythonServiceUrl, [
'topic' => $topic,
'callback_url' => $callbackUrl
]);
$resData = $response->json();
if (isset($resData['code']) && $resData['code'] == 200) {
// 可以在这里把任务状态写入数据库,标记为 "进行中"
return json(['code' => 200, 'msg' => 'AI 团队已开始工作,请稍后查看结果']);
}
return json(['code' => 400, 'msg' => '唤醒 AI 团队失败', 'error' => $resData]);
} catch (\Exception $e) {
Log::error('调用 CrewAI 出错:' . $e->getMessage());
return json(['code' => 500, 'msg' => '服务器内部错误']);
}
}
/**
* 接收 CrewAI 异步跑完后的结果回调
* URL: http://your-domain/ai_agent/callback
*/
public function callback()
{
// 1. 接收 Python 传回的 JSON 数据
$data = $this->request->param();
Log::info('收到 CrewAI 回调数据:' . json_encode($data, JSON_UNESCAPED_UNICODE));
if (empty($data) || !isset($data['result'])) {
return json(['code' => 400, 'msg' => '非法回调数据']);
}
// 2. 处理业务逻辑:例如将结果存入数据库
$insertData = [
'topic' => $data['topic'] ?? '未知主题',
'content' => $data['result'],
'status' => $data['status'] ?? 'success',
'create_time' => time()
];
// 假设你有一张 ai_reports 表
// Db::name('ai_reports')->insert($insertData);
// 3. 必须给 Python 服务一个响应,确认收到
return json(['code' => 200, 'msg' => 'TP6 成功接收并保存报告']);
}
}
请谨慎使用此类代码。
第三步:配置路由 (route\app.php)
让接口对外的 URL 更美观,在路由文件中加入:
php
use think\facade\Route;
// 发起 AI 任务
Route::post('ai/research', 'AiAgent/createTask');
// 接收 AI 结果(注意:由于是跨服务 POST,需确保该接口没有被全局的 CSRF 中间件拦截)
Route::post('ai/callback', 'AiAgent/callback');
请谨慎使用此类代码。
💡 为什么采用这种架构?
彻底解耦: TP6 擅长处理复杂的 MySQL 事务、用户权限、高并发 Web 请求;Python 擅长运行大模型流式传输和多 Agent 复杂逻辑。两者各司其职。
避免超时 (Timeout): CrewAI 的多个智能体互相讨论、上网查资料往往需要 30 秒甚至数分钟。如果用 TP6 同步等待,PHP 进程会被挂死并报 504 超时。通过 FastAPI 异步后台任务 + TP6 Webhook 回调,完美解决了超时问题。