FAQ
常见问题与排查指南。
环境与安装
Python 版本要求
ArtifactFlow 需要 Python 3.10+,因为代码使用了 X | Y union 类型语法(PEP 604)等 3.10 特性。
检查版本:
web_fetch 抓取限额 (Jina 429)
Jina Reader API 免费 tier 有请求限额。命中限额时工具会自动等待 30 秒重试(最多 2 次),重试耗尽后降级到 BeautifulSoup(HTML)或 DocConverter + pymupdf(PDF)。
提升限额:
已知限制: PDF 降级路径通过 URL 后缀(.pdf)判断类型。签名下载链接(如 download?file=xxx)在 Jina 失败后会走 HTML 降级路径
aiosqlite 版本冲突
错误信息:
原因: LangGraph 和其他包对 aiosqlite 版本要求不一致。
解决方案:
认证问题
服务启动报 ARTIFACTFLOW_JWT_SECRET 未设置
服务启动时会检查 JWT 密钥,未设置则拒绝启动:
解决方案:
# 生成并设置 JWT 密钥
export ARTIFACTFLOW_JWT_SECRET=$(python -c "import secrets; print(secrets.token_urlsafe(32))")
# 或写入 .env 文件(推荐)
echo "ARTIFACTFLOW_JWT_SECRET=$(python -c 'import secrets; print(secrets.token_urlsafe(32))')" >> .env
如何创建第一个管理员账号?
python scripts/create_admin.py admin
# 按提示输入密码
# 或直接指定密码
python scripts/create_admin.py admin --password your_password
该脚本会:
1. 创建 admin 角色的用户
2. 将所有 user_id 为空的历史对话归属到该用户(可用 --no-claim 跳过)
CLI 报 401 / "Not authenticated"
CLI 需要先登录获取 token:
如果 token 过期,重新执行 login 即可。
前端跳转到登录页 / 频繁登出
可能原因:
- Token 过期:默认有效期 7 天,重新登录即可
- 用户被禁用:管理员通过
PUT /auth/users/{id}禁用了账号(is_active=false),联系管理员 - JWT 密钥变更:服务端重启后使用了不同的
ARTIFACTFLOW_JWT_SECRET,所有旧 token 失效
SSE 连接返回 401
SSE 端点同样需要认证。确保前端使用 fetch(而非 EventSource)连接 SSE,以便携带 Authorization header。ArtifactFlow 前端已正确处理(frontend/src/lib/sse.ts)。
运行问题
API 服务启动失败
检查端口占用:
检查数据库目录:
SSE 连接立即断开
可能原因:
- thread_id 不存在:检查 POST /chat 返回的 thread_id
- TTL 超时:POST 后超过 30 秒未连接 SSE
- 反向代理缓冲:Nginx 等代理可能缓冲 SSE
Nginx 配置:
location /api/v1/stream/ {
proxy_pass http://backend;
proxy_buffering off;
proxy_cache off;
proxy_set_header Connection '';
proxy_http_version 1.1;
chunked_transfer_encoding off;
}
Agent 执行卡住
启用调试日志:
检查 LLM API:
# 测试 API 连接
curl -X POST https://your-llm-api/v1/chat/completions \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"model": "your-model", "messages": [{"role": "user", "content": "test"}]}'
检查环境变量:
权限中断后无法恢复
检查 Checkpointer 状态:
# 查看 LangGraph 数据库
sqlite3 data/langgraph.db ".tables"
sqlite3 data/langgraph.db "SELECT thread_id FROM checkpoints LIMIT 5"
确保 thread_id 一致:
# 通过 API 恢复执行
# POST /api/v1/chat/{conversation_id}/resume
{
"thread_id": "thd-original-thread-id", # 使用原始 thread_id
"message_id": "msg-original-message-id",
"approved": True
}
或通过 Controller:
async for event in controller.stream_execute(
thread_id=original_thread_id,
conversation_id=conversation_id,
message_id=message_id,
resume_data={"type": "permission", "approved": True}
):
# 处理事件
pass
工具问题
web_search 返回空结果
检查搜索 API 配置:
搜索后端使用博查 AI(Bocha API),确保 .env 中配置了 BOCHA_API_KEY:
web_fetch 抓取失败
调整抓取参数:
# web_fetch 工具支持的参数
result = await tool.execute(
url="https://example.com", # URL(必填)
max_content_length=20000, # 最大字符数(默认 20000)
)
检查目标网站:
- 是否有反爬虫机制(Jina Reader 通常能处理,但部分站点可能拦截)
- 是否需要代理
Artifact 更新版本冲突
错误信息:
原因: 多个 Agent 同时更新同一个 Artifact。
解决方案: Agent 应该:
- 重新读取最新版本
- 合并变更
- 重试更新
这是正常的并发控制机制,不是 bug。
性能问题
LLM 响应慢
使用流式输出: 确保前端使用 SSE 接收 llm_chunk 事件,而不是等待完整响应。
调整模型:
内存使用过高
检查 StreamManager 队列:
# 获取活跃流数量
print(f"Active streams: {stream_manager.active_stream_count}")
# 检查特定流状态
status = stream_manager.get_stream_status(thread_id)
print(f"Stream status: {status}") # pending | streaming | closed | None
调整 TTL:
数据库变慢
清理历史数据:
-- 删除 30 天前的对话
DELETE FROM messages WHERE created_at < datetime('now', '-30 days');
DELETE FROM conversations WHERE updated_at < datetime('now', '-30 days');
-- 清理 Artifact 历史版本(保留每个 artifact 最近 10 个版本)
DELETE FROM artifact_versions
WHERE id NOT IN (
SELECT id FROM (
SELECT id, ROW_NUMBER() OVER (
PARTITION BY artifact_id, session_id
ORDER BY version DESC
) as rn
FROM artifact_versions
) WHERE rn <= 10
);
-- 重建索引
VACUUM;
开发问题
如何查看完整的 Agent 提示词?
from agents.lead_agent import LeadAgent
agent = LeadAgent()
# build_system_prompt 只返回角色定义部分
base_prompt = agent.build_system_prompt(context=None)
print("=== Base Prompt ===")
print(base_prompt)
# build_complete_system_prompt 返回包含工具说明的完整提示词
# 需要先绑定 toolkit
if agent.toolkit:
complete_prompt = agent.build_complete_system_prompt(context=None)
print("=== Complete Prompt ===")
print(complete_prompt)
如何调试工具执行?
# 直接测试工具
from tools.implementations.web_search import WebSearchTool
tool = WebSearchTool()
result = await tool(query="test query") # 使用 __call__,会自动填充默认参数
print(result)
如何查看 Graph 状态?
# 获取当前状态快照
from langgraph.checkpoint.sqlite.aio import AsyncSqliteSaver
checkpointer = AsyncSqliteSaver.from_conn_string("data/langgraph.db")
state = await checkpointer.aget({"configurable": {"thread_id": "your-thread-id"}})
print(state)
获取帮助
如果以上都无法解决问题:
- 检查日志:
tail -f logs/artifactflow.log - 启用调试模式:
set_global_debug(True) - 提交 Issue:附上错误日志和复现步骤