Skip to content

Commit 87b5723

Browse files
Copilotks6088ts
andcommitted
Changes before error encountered
Co-authored-by: ks6088ts <[email protected]>
1 parent 0dcae76 commit 87b5723

File tree

11 files changed

+730
-2
lines changed

11 files changed

+730
-2
lines changed

.env.template

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@ AZURE_BLOB_STORAGE_CONTAINER_NAME="files"
1818
AZURE_AI_SPEECH_API_KEY="<YOUR_AZURE_AI_SPEECH_API_KEY>"
1919
AZURE_AI_SPEECH_ENDPOINT="https://<speech-api-name>.cognitiveservices.azure.com/"
2020

21+
# Azure AI Foundry
22+
AZURE_AI_FOUNDRY_PROJECT_CONNECTION_STRING="https://<YOUR_PROJECT_NAME>.eastus.inference.ai.azure.com"
23+
AZURE_AI_FOUNDRY_API_KEY="<YOUR_API_KEY>"
24+
AZURE_AI_FOUNDRY_PROJECT_ID="<YOUR_PROJECT_ID>"
25+
2126
# Chats WebSocket
2227
# Azure Container Apps: `wss://yourcontainerapps.japaneast.azurecontainerapps.io`
2328
CHATS_WEBSOCKET_URL="ws://localhost:8000"

docs/index.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,3 +194,27 @@ az resource update \
194194
### Azure AI Speech
195195

196196
- [バッチ文字起こしとは](https://learn.microsoft.com/ja-jp/azure/ai-services/speech-service/batch-transcription)
197+
198+
### Azure AI Foundry
199+
200+
- [Quickstart: Create a new agent](https://learn.microsoft.com/en-us/azure/ai-foundry/agents/quickstart?pivots=programming-language-python-azure)
201+
- [Deep Research tool (preview)](https://learn.microsoft.com/en-us/azure/ai-foundry/agents/quickstart?pivots=programming-language-python-azure)
202+
203+
#### CLI 実行例
204+
205+
```bash
206+
# エージェントを作成
207+
python scripts/agents.py create-agent "研究アシスタント" --description "研究をサポートするAIアシスタント" --instructions "あなたは研究者をサポートするAIアシスタントです。質問に対して詳細で正確な回答を提供してください。"
208+
209+
# エージェント一覧を取得
210+
python scripts/agents.py list-agents
211+
212+
# エージェントの詳細を取得
213+
python scripts/agents.py get-agent <agent_id>
214+
215+
# エージェントとチャット
216+
python scripts/agents.py chat <agent_id> "機械学習の最新トレンドについて教えてください"
217+
218+
# エージェントを削除
219+
python scripts/agents.py delete-agent <agent_id>
220+
```

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ description = "A GitHub template repository for Python"
55
readme = "README.md"
66
requires-python = ">=3.10"
77
dependencies = [
8+
"azure-ai-projects>=1.0.0b12",
89
"azure-cosmos>=4.9.0",
910
"azure-functions>=1.23.0",
1011
"azure-identity>=1.23.0",

scripts/agents.py

Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
#!/usr/bin/env python
2+
# filepath: /home/runner/work/template-fastapi/template-fastapi/scripts/agents.py
3+
4+
import json
5+
6+
import typer
7+
from rich.console import Console
8+
from rich.table import Table
9+
10+
from template_fastapi.models.agent import AgentRequest, ChatRequest
11+
from template_fastapi.repositories.agents import AgentRepository
12+
13+
app = typer.Typer()
14+
console = Console()
15+
agent_repo = AgentRepository()
16+
17+
18+
@app.command()
19+
def create_agent(
20+
name: str = typer.Argument(..., help="エージェント名"),
21+
description: str | None = typer.Option(None, "--description", "-d", help="エージェントの説明"),
22+
instructions: str | None = typer.Option(None, "--instructions", "-i", help="エージェントの指示"),
23+
model: str = typer.Option("gpt-4o", "--model", "-m", help="使用するモデル"),
24+
):
25+
"""新しいエージェントを作成する"""
26+
console.print("[bold green]新しいエージェントを作成します[/bold green]")
27+
console.print(f"名前: {name}")
28+
console.print(f"説明: {description or 'なし'}")
29+
console.print(f"指示: {instructions or 'なし'}")
30+
console.print(f"モデル: {model}")
31+
32+
try:
33+
request = AgentRequest(
34+
name=name,
35+
description=description,
36+
instructions=instructions,
37+
model=model,
38+
)
39+
40+
agent = agent_repo.create_agent(request)
41+
42+
console.print("\n[bold blue]エージェントが正常に作成されました[/bold blue]:")
43+
console.print(f"ID: {agent.id}")
44+
console.print(f"名前: {agent.name}")
45+
console.print(f"説明: {agent.description}")
46+
console.print(f"指示: {agent.instructions}")
47+
console.print(f"モデル: {agent.model}")
48+
console.print(f"ステータス: {agent.status}")
49+
console.print(f"作成日時: {agent.created_at}")
50+
51+
except Exception as e:
52+
console.print(f"❌ [bold red]エラー[/bold red]: {str(e)}")
53+
54+
55+
@app.command()
56+
def get_agent(
57+
agent_id: str = typer.Argument(..., help="エージェントID"),
58+
):
59+
"""エージェントの情報を取得する"""
60+
console.print("[bold green]エージェント情報を取得します[/bold green]")
61+
console.print(f"エージェントID: {agent_id}")
62+
63+
try:
64+
agent = agent_repo.get_agent(agent_id)
65+
66+
console.print("\n[bold blue]エージェント情報[/bold blue]:")
67+
console.print(f"ID: {agent.id}")
68+
console.print(f"名前: {agent.name}")
69+
console.print(f"説明: {agent.description}")
70+
console.print(f"指示: {agent.instructions}")
71+
console.print(f"モデル: {agent.model}")
72+
console.print(f"ステータス: {agent.status}")
73+
console.print(f"作成日時: {agent.created_at}")
74+
console.print(f"更新日時: {agent.updated_at}")
75+
76+
if agent.tools:
77+
console.print(f"ツール: {json.dumps(agent.tools, indent=2, ensure_ascii=False)}")
78+
79+
except Exception as e:
80+
console.print(f"❌ [bold red]エラー[/bold red]: {str(e)}")
81+
82+
83+
@app.command()
84+
def list_agents(
85+
limit: int = typer.Option(10, "--limit", "-l", help="取得する件数"),
86+
offset: int = typer.Option(0, "--offset", "-o", help="オフセット"),
87+
):
88+
"""エージェントの一覧を取得する"""
89+
console.print("[bold green]エージェント一覧を取得します[/bold green]")
90+
console.print(f"取得件数: {limit}")
91+
console.print(f"オフセット: {offset}")
92+
93+
try:
94+
agents_response = agent_repo.list_agents(limit=limit, offset=offset)
95+
96+
if not agents_response.agents:
97+
console.print("[yellow]エージェントが見つかりません[/yellow]")
98+
return
99+
100+
table = Table(title="エージェント一覧")
101+
table.add_column("ID", style="cyan")
102+
table.add_column("名前", style="magenta")
103+
table.add_column("説明", style="green")
104+
table.add_column("モデル", style="blue")
105+
table.add_column("ステータス", style="yellow")
106+
table.add_column("作成日時", style="dim")
107+
108+
for agent in agents_response.agents:
109+
table.add_row(
110+
agent.id,
111+
agent.name,
112+
agent.description or "なし",
113+
agent.model,
114+
agent.status,
115+
agent.created_at,
116+
)
117+
118+
console.print(table)
119+
console.print(f"[bold blue]合計: {agents_response.total}件[/bold blue]")
120+
121+
except Exception as e:
122+
console.print(f"❌ [bold red]エラー[/bold red]: {str(e)}")
123+
124+
125+
@app.command()
126+
def delete_agent(
127+
agent_id: str = typer.Argument(..., help="エージェントID"),
128+
):
129+
"""エージェントを削除する"""
130+
console.print("[bold red]エージェントを削除します[/bold red]")
131+
console.print(f"エージェントID: {agent_id}")
132+
133+
confirm = typer.confirm("本当に削除しますか?")
134+
if not confirm:
135+
console.print("[yellow]削除をキャンセルしました[/yellow]")
136+
return
137+
138+
try:
139+
success = agent_repo.delete_agent(agent_id)
140+
141+
if success:
142+
console.print("[bold green]エージェントが正常に削除されました[/bold green]")
143+
else:
144+
console.print("[bold red]エージェントの削除に失敗しました[/bold red]")
145+
146+
except Exception as e:
147+
console.print(f"❌ [bold red]エラー[/bold red]: {str(e)}")
148+
149+
150+
@app.command()
151+
def chat(
152+
agent_id: str = typer.Argument(..., help="エージェントID"),
153+
message: str = typer.Argument(..., help="メッセージ"),
154+
thread_id: str | None = typer.Option(None, "--thread-id", "-t", help="スレッドID"),
155+
):
156+
"""エージェントとチャットする"""
157+
console.print("[bold green]エージェントとチャットします[/bold green]")
158+
console.print(f"エージェントID: {agent_id}")
159+
console.print(f"メッセージ: {message}")
160+
console.print(f"スレッドID: {thread_id or '新規作成'}")
161+
162+
try:
163+
request = ChatRequest(
164+
message=message,
165+
thread_id=thread_id,
166+
)
167+
168+
response = agent_repo.chat_with_agent(agent_id, request)
169+
170+
console.print("\n[bold blue]チャット結果[/bold blue]:")
171+
console.print(f"メッセージID: {response.id}")
172+
console.print(f"スレッドID: {response.thread_id}")
173+
console.print(f"あなた: {response.message}")
174+
console.print(f"エージェント: {response.response}")
175+
console.print(f"作成日時: {response.created_at}")
176+
177+
except Exception as e:
178+
console.print(f"❌ [bold red]エラー[/bold red]: {str(e)}")
179+
180+
181+
if __name__ == "__main__":
182+
app()

template_fastapi/app.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
from opentelemetry.instrumentation.fastapi import FastAPIInstrumentor
1212
from opentelemetry.trace import Span
1313

14-
from template_fastapi.routers import chats, demos, files, foodies, games, items, speeches
14+
from template_fastapi.routers import agents, chats, demos, files, foodies, games, items, speeches
1515

1616
app = FastAPI()
1717

@@ -43,3 +43,4 @@ def server_request_hook(span: Span, scope: dict):
4343
app.include_router(files.router)
4444
app.include_router(speeches.router)
4545
app.include_router(chats.router)
46+
app.include_router(agents.router)

template_fastapi/models/agent.py

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
from enum import Enum
2+
from typing import Any
3+
4+
from pydantic import BaseModel
5+
6+
7+
class AgentStatus(str, Enum):
8+
"""Agent status enumeration"""
9+
10+
ACTIVE = "active"
11+
INACTIVE = "inactive"
12+
DELETED = "deleted"
13+
14+
15+
class AgentRequest(BaseModel):
16+
"""Request model for creating an agent"""
17+
18+
name: str
19+
description: str | None = None
20+
instructions: str | None = None
21+
model: str = "gpt-4o"
22+
tools: list[dict[str, Any]] | None = None
23+
24+
25+
class AgentResponse(BaseModel):
26+
"""Response model for agent operations"""
27+
28+
id: str
29+
name: str
30+
description: str | None = None
31+
instructions: str | None = None
32+
model: str
33+
tools: list[dict[str, Any]] | None = None
34+
status: AgentStatus
35+
created_at: str
36+
updated_at: str
37+
38+
39+
class ChatRequest(BaseModel):
40+
"""Request model for chat with agent"""
41+
42+
message: str
43+
thread_id: str | None = None
44+
45+
46+
class ChatResponse(BaseModel):
47+
"""Response model for chat with agent"""
48+
49+
id: str
50+
agent_id: str
51+
thread_id: str
52+
message: str
53+
response: str
54+
created_at: str
55+
56+
57+
class AgentListResponse(BaseModel):
58+
"""Response model for listing agents"""
59+
60+
agents: list[AgentResponse]
61+
total: int

0 commit comments

Comments
 (0)