first add

This commit is contained in:
lingyuzeng
2025-08-27 16:14:23 +08:00
commit 01a4190a28
3 changed files with 298 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
.venv/
Qwen-Agent/

46
README.md Normal file
View File

@@ -0,0 +1,46 @@
## Agent
自建基于llama-box启动qwen3-code-flash-1M 的 AI Agent 代码仓库
### llama-box 启动参数
注意:
添加 --enable-reasoning这个参数对 Qwen3 模型的工具调用非常重要,能够提升推理能力。
添加 --jinja这个参数用于加载 Jinja 模板Qwen3 模型需要使用 Jinja 模板进行推理。、
启动参数参考:
```bash
llama-box \
--host 0.0.0.0 \
--port 8080 \
--model /Volumes/long990max/gpustack_data/unsloth/Qwen3-Coder-30B-A3B-Instruct-1M-GGUF/Qwen3-Coder-30B-A3B-Instruct-1M-UD-Q4_K_XL.gguf \
--chat-template chatml \
--jinja \
--enable-reasoning \
--flash-attn \
--cache-type-k q4_0 \
--cache-type-v q4_0 \
--ctx-size 262144 \
--gpu-layers 49 \
--threads 12 \
--threads-batch 16 \
--threads-http 16 \
--batch-size 1024 \
--ubatch-size 1024 \
--defrag-thold -1 \
--no-context-shift
```
### 安装环境
```bash
uv venv --managed-python -p 3.12 --seed .venv
source .venv/bin/activate
git clone https://github.com/hotwa/Qwen-Agent
cd Qwen-Agent
uv pip install -e ./"[gui,rag,code_interpreter,mcp]"
cd ..
python qwen3_coder_with_qwen_agent.py
```

View File

@@ -0,0 +1,250 @@
"""
Qwen3-Coder 使用 Qwen-Agent 框架测试示例
这个示例演示了如何使用 Qwen-Agent 框架调用 qwen3-coder 模型进行工具调用测试。
工具配置说明:
1. MCP工具通过'mcpServers'配置需要安装对应的MCP服务器
- time: 获取当前时间的MCP工具
- fetch: 网络请求工具
- filesystem: 文件系统操作工具
这些工具需要额外安装对应的MCP服务器才能使用
2. 原生工具Qwen-Agent内置的工具直接可用
- 'code_interpreter': 代码解释器可以执行Python代码
- 'image_gen': 图像生成工具
- 'web_search': 网络搜索工具
- 'calculator''python_executor': Python代码执行器可作为计算器
环境变量说明:
- MAX_LLM_CALL_PER_RUN: 控制LLM调用的最大轮数不是工具调用次数
这个限制是针对整个对话的LLM调用轮数包括初始调用和后续基于工具结果的调用
- MAX_TOOL_CALLS_PER_TURN: 控制每轮LLM输出中可触发的工具调用数量
这个限制是针对单次LLM响应中可以触发的工具数量防止模型一次性触发过多工具
"""
import os
# 设置环境变量以控制工具调用行为
# MAX_LLM_CALL_PER_RUN: 控制LLM调用的最大轮数不是工具调用次数
# MAX_TOOL_CALLS_PER_TURN: 控制每轮LLM输出中可触发的工具调用数量
os.environ["MAX_LLM_CALL_PER_RUN"] = "8"
os.environ["MAX_TOOL_CALLS_PER_TURN"] = "8"
import sys
import traceback
from pathlib import Path
# 添加项目路径到Python路径
project_root = Path(__file__).parent.parent.parent
sys.path.insert(0, str(project_root))
try:
from qwen_agent.agents import Assistant
from qwen_agent.gui import WebUI
from qwen_agent.utils.output_beautify import typewriter_print
except ImportError as e:
print(f"❌ 导入失败: {e}")
print("请确保已安装 qwen-agent: pip install qwen-agent")
sys.exit(1)
def init_agent_service():
"""初始化Agent服务"""
# 配置API参数使用OpenAI兼容模式
llm_cfg = {
'model': 'qwen3-coder-flash-1M',
'model_server': 'https://ai.jmsu.top/v1',
'api_key': 'gpustack_96d105073565a038_23d7fe2768b4b27f9d92ab4661452ade',
'generate_cfg': {
# 使用API的原生工具调用接口
'temperature': 0.7,
'top_p': 0.8,
'fncall_prompt_type': 'qwen', # 对 Qwen3 通常更稳
},
}
# 配置工具
tools = [
{
'mcpServers': { # 指定MCP配置
'time': {
'command': 'uvx',
'args': ['mcp-server-time', '--local-timezone=Asia/Shanghai']
},
'fetch': {
'command': 'uvx',
'args': ['mcp-server-fetch']
},
'filesystem': {
'command': 'npx',
'args': [
'-y',
'@modelcontextprotocol/server-filesystem',
'~/Desktop/'
]
},
}
},
# 添加一些原生工具示例
'code_interpreter', # 代码解释器
'web_search', # 网络搜索
]
# 创建Agent
bot = Assistant(
llm=llm_cfg,
function_list=tools,
name='Qwen3-Coder Tool-calling Demo',
description="I'm a demo using the Qwen3-Coder tool calling. Welcome to add and play with your own tools!"
)
return bot
def test(query: str = '现在几点了?'):
"""测试函数"""
print("=== Qwen3-Coder 使用 Qwen-Agent 测试 ===\n")
# 初始化Agent
bot = init_agent_service()
# 进行对话
messages = [{'role': 'user', 'content': query}]
print(f"💬 用户: {query}")
print("🤖 助手: ", end='', flush=True)
# 缓存最终回复内容
final_response = ""
current_tool_call = ""
in_tool_call = False
try:
for response in bot.run(messages=messages):
# 处理响应
if response:
for msg in response:
if msg['role'] == 'assistant':
if msg.get('content'):
# 检查是否包含工具调用标记
if '[TOOL_CALL]' in msg['content']:
in_tool_call = True
current_tool_call = msg['content']
# 清空之前的输出,准备显示工具调用
print(f"\r🤖 助手: {msg['content']}", end='', flush=True)
elif in_tool_call:
# 继续工具调用信息
current_tool_call += msg['content']
print(msg['content'], end='', flush=True)
else:
# 普通回复内容
final_response += msg['content']
# 不再实时打印,等待工具调用完成后统一显示
# print(msg['content'], end='', flush=True)
elif msg['role'] == 'function':
# 工具响应,显示工具结果
in_tool_call = False
print(f"\n[TOOL_RESPONSE] {msg.get('name', 'unknown')}")
print(msg.get('content', ''))
# 重置最终回复内容,准备接收新的回复
final_response = ""
# 输出最终结果
if final_response:
print("\r🤖 助手: ", end='', flush=True)
print(final_response, end='', flush=True)
print() # 输出完成后换行
except Exception as e:
print(f"\n❌ 调用失败: {e}")
import traceback
traceback.print_exc()
def app_tui():
"""命令行交互模式"""
print("=== Qwen3-Coder 使用 Qwen-Agent 命令行交互模式 ===\n")
# 初始化Agent
bot = init_agent_service()
# 进行对话
messages = []
while True:
query = input('user question: ')
if query.lower() in ['quit', 'exit', '退出']:
print("👋 再见!")
break
messages.append({'role': 'user', 'content': query})
response = []
response_plain_text = ''
print("🤖 助手: ", end='', flush=True)
try:
for response in bot.run(messages=messages):
# 添加调试信息
# print(f"[DEBUG] 收到响应: {type(response)}", file=sys.stderr)
# 使用 typewriter_print 实现流式输出
if response:
try:
response_plain_text = typewriter_print(response, response_plain_text)
except Exception as e:
# 如果typewriter_print出错尝试直接打印
# print(f"[WARNING] typewriter_print出错: {e}", file=sys.stderr)
if isinstance(response, list):
for item in response:
if isinstance(item, dict) and 'content' in item:
print(item['content'], end='', flush=True)
elif isinstance(item, dict) and 'message' in item:
print(item['message'], end='', flush=True)
print() # 输出完成后换行
messages.extend(response)
except Exception as e:
print(f"\n❌ 调用失败: {e}")
import traceback
traceback.print_exc()
def app_gui():
"""图形界面模式"""
# 初始化Agent
bot = init_agent_service()
chatbot_config = {
'prompt.suggestions': [
'现在几点了?',
'请用Python写一个计算斐波那契数列的函数',
'帮我搜索一下Python装饰器的用法'
]
}
WebUI(
bot,
chatbot_config=chatbot_config,
).run()
def main():
"""主函数"""
print("🚀 Qwen3-Coder 使用 Qwen-Agent 测试示例")
print("=" * 50)
print("\n请选择运行模式:")
print("1. 简单测试 - 固定问题")
print("2. 命令行交互模式")
print("3. 图形界面模式")
choice = input("\n请输入选项 (1-3): ").strip()
if choice == "1":
test()
elif choice == "2":
app_tui()
elif choice == "3":
app_gui()
else:
print("❌ 无效选项,运行默认测试")
test()
if __name__ == '__main__':
main()